diff --git a/.gitignore b/.gitignore index e351df955..e38d6695f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -scripts/__pycache__/* \ No newline at end of file +scripts/__pycache__/* +**/.DS_Store diff --git a/.pages b/.pages index 1b165097d..dd1646162 100644 --- a/.pages +++ b/.pages @@ -1,6 +1,5 @@ nav: - - index.md - - build - - tutorials - - learn - - 'AI Resources': ai-resources.md +- products +- protocol +- tools +- ai-resources \ No newline at end of file diff --git a/.snippets/code/build/queries/use-queries/query-request-with-api-key.jsx b/.snippets/code/build/queries/use-queries/query-request-with-api-key.jsx deleted file mode 100644 index 2e37105b4..000000000 --- a/.snippets/code/build/queries/use-queries/query-request-with-api-key.jsx +++ /dev/null @@ -1,8 +0,0 @@ -const serialized = request.serialize(); -const proxyResponse = (await axios.post)( - QUERY_URL, - { - bytes: Buffer.from(serialized).toString('hex'), - }, - { headers: { 'X-API-Key': YOUR_API_KEY } } -); diff --git a/.snippets/code/build/transfers/connect/overview/cdn-with-version.html b/.snippets/code/build/transfers/connect/overview/cdn-with-version.html deleted file mode 100644 index 7ee5dd59f..000000000 --- a/.snippets/code/build/transfers/connect/overview/cdn-with-version.html +++ /dev/null @@ -1,12 +0,0 @@ - -
- - - - diff --git a/.snippets/code/build/transfers/connect/overview/cdn.html b/.snippets/code/build/transfers/connect/overview/cdn.html deleted file mode 100644 index 3b6696d11..000000000 --- a/.snippets/code/build/transfers/connect/overview/cdn.html +++ /dev/null @@ -1,12 +0,0 @@ - -
- - - - diff --git a/.snippets/code/build/transfers/connect/overview/import-v0.js b/.snippets/code/build/transfers/connect/overview/import-v0.js deleted file mode 100644 index 46f1b6fab..000000000 --- a/.snippets/code/build/transfers/connect/overview/import-v0.js +++ /dev/null @@ -1,7 +0,0 @@ -import WormholeConnect from '@wormhole-foundation/wormhole-connect'; - -function App() { - return ( - - ); -} \ No newline at end of file diff --git a/.snippets/code/build/transfers/connect/overview/import-v1.js b/.snippets/code/build/transfers/connect/overview/import-v1.js deleted file mode 100644 index 02604db36..000000000 --- a/.snippets/code/build/transfers/connect/overview/import-v1.js +++ /dev/null @@ -1,5 +0,0 @@ -import WormholeConnect from '@wormhole-foundation/wormhole-connect'; - -function App() { - return ; -} diff --git a/.snippets/code/products/cctp-bridge/get-started/snippet-1.ts b/.snippets/code/products/cctp-bridge/get-started/snippet-1.ts new file mode 100644 index 000000000..a7e6f99c9 --- /dev/null +++ b/.snippets/code/products/cctp-bridge/get-started/snippet-1.ts @@ -0,0 +1,54 @@ +import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; + +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } + + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} diff --git a/.snippets/code/products/cctp-bridge/get-started/snippet-2.ts b/.snippets/code/products/cctp-bridge/get-started/snippet-2.ts new file mode 100644 index 000000000..65017af41 --- /dev/null +++ b/.snippets/code/products/cctp-bridge/get-started/snippet-2.ts @@ -0,0 +1,56 @@ +import { CircleTransfer, wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { getSigner } from './helper'; + +(async function () { + // Initialize the Wormhole object for the Testnet environment and add supported chains (evm, solana and sui) + const wh = await wormhole('Testnet', [evm, solana, sui]); + + // Grab chain Contexts -- these hold a reference to a cached rpc client + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Sepolia'); + + // Get signer from local key + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the amount of USDC to transfer (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) + const amt = 100_000n; + + const automatic = false; + + // Create the circleTransfer transaction (USDC-only) + const xfer = await wh.circleTransfer( + amt, + source.address, + destination.address, + automatic + ); + + const quote = await CircleTransfer.quoteTransfer( + sendChain, + rcvChain, + xfer.transfer + ); + console.log('Quote: ', quote); + + // Step 1: Initiate the transfer on the source chain (Avalanche) + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + // Step 2: Wait for Circle Attestation (VAA) + const timeout = 120 * 1000; // Timeout in milliseconds (120 seconds) + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(timeout); + console.log(`Got Attestation: `, attestIds); + + // Step 3: Complete the transfer on the destination chain (Sepolia) + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, dstTxids); + + process.exit(0); +})(); diff --git a/.snippets/code/products/cctp-bridge/get-started/snippet-3.html b/.snippets/code/products/cctp-bridge/get-started/snippet-3.html new file mode 100644 index 000000000..53983a1b3 --- /dev/null +++ b/.snippets/code/products/cctp-bridge/get-started/snippet-3.html @@ -0,0 +1,22 @@ +
+ npx tsx transfer.ts + Starting Transfer + Started Transfer: + [ '0xdedbf496a1e658efb15bc57f120122b38a3714a560892be7a8c0a7f23c44aca2', + '0x9a8e41837e225edfa62d1913f850c01bd0552e55bf082fd9225df789455a465a' ] + + Waiting for Attestation + Retrying Circle:GetAttestation, attempt 0/60 + Retrying Circle:GetAttestation, attempt 1/60 + + Got Attestation: [{hash: '0x89f8651bf94cfd932ba5bcd2f7795a3fabc6a7c602075fa712c9c55022f5cca8'}] + + Completing Transfer + Completed Transfer: + [ '0x9b81bb30d2a68aa2ecc707a8a1b5af63448223a69b2ead6cf6d172ab880ad0c9'] + +
diff --git a/.snippets/code/build/transfers/cctp/CCTPReceiver.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/CCTPReceiver.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/CCTPReceiver.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/CCTPReceiver.sol diff --git a/.snippets/code/build/transfers/cctp/CCTPSender.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/CCTPSender.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/CCTPSender.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/CCTPSender.sol diff --git a/.snippets/code/build/transfers/cctp/CircleIntegration.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/CircleIntegration.sol similarity index 99% rename from .snippets/code/build/transfers/cctp/CircleIntegration.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/CircleIntegration.sol index 68b54b367..2a2bbe973 100644 --- a/.snippets/code/build/transfers/cctp/CircleIntegration.sol +++ b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/CircleIntegration.sol @@ -69,7 +69,7 @@ contract CircleIntegration is // Call the circle bridge and `depositForBurnWithCaller`. The `mintRecipient` // should be the target contract (or wallet) composing on this contract. - (uint64 nonce, uint256 amountReceived) = _transferTokens( + (uint64 nonce, uint256 amountReceived) = _transferTokens{value: wormholeFee}( transferParams.token, transferParams.amount, transferParams.targetChain, diff --git a/.snippets/code/build/transfers/cctp/MessageTransmitter.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/MessageTransmitter.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/MessageTransmitter.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/MessageTransmitter.sol diff --git a/.snippets/code/build/transfers/cctp/TokenMessenger.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/TokenMessenger.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/TokenMessenger.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/TokenMessenger.sol diff --git a/.snippets/code/build/transfers/cctp/TokenMinter.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/TokenMinter.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/TokenMinter.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/TokenMinter.sol diff --git a/.snippets/code/build/transfers/cctp/receivePayloadAndUSDC.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/receivePayloadAndUSDC.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/receivePayloadAndUSDC.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/receivePayloadAndUSDC.sol diff --git a/.snippets/code/build/transfers/cctp/sendCrossChainDeposit.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/sendCrossChainDeposit.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/sendCrossChainDeposit.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/sendCrossChainDeposit.sol diff --git a/.snippets/code/build/transfers/cctp/sendUSDCWithPayloadToEvm.sol b/.snippets/code/products/cctp-bridge/guides/cctp-contracts/sendUSDCWithPayloadToEvm.sol similarity index 100% rename from .snippets/code/build/transfers/cctp/sendUSDCWithPayloadToEvm.sol rename to .snippets/code/products/cctp-bridge/guides/cctp-contracts/sendUSDCWithPayloadToEvm.sol diff --git a/.snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-1.ts b/.snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-1.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-1.ts rename to .snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-1.ts diff --git a/.snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts b/.snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts rename to .snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts diff --git a/.snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts b/.snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts rename to .snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts diff --git a/.snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-4.ts b/.snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-4.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-4.ts rename to .snippets/code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-4.ts diff --git a/.snippets/code/build/transfers/connect/configuration/advanced-configuration.json b/.snippets/code/products/connect/configuration/configuration-v0/advanced-configuration.json similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/advanced-configuration.json rename to .snippets/code/products/connect/configuration/configuration-v0/advanced-configuration.json diff --git a/.snippets/code/build/transfers/connect/configuration/arbitrary-token.tsx b/.snippets/code/products/connect/configuration/configuration-v0/arbitrary-token.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/arbitrary-token.tsx rename to .snippets/code/products/connect/configuration/configuration-v0/arbitrary-token.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/configure-html.html b/.snippets/code/products/connect/configuration/configuration-v0/configure-html.html similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/configure-html.html rename to .snippets/code/products/connect/configuration/configuration-v0/configure-html.html diff --git a/.snippets/code/build/transfers/connect/configuration/configure-react-v0.tsx b/.snippets/code/products/connect/configuration/configuration-v0/configure-react-v0.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/configure-react-v0.tsx rename to .snippets/code/products/connect/configuration/configuration-v0/configure-react-v0.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-full.jsx b/.snippets/code/products/connect/configuration/configuration-v0/custom-full.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-full.jsx rename to .snippets/code/products/connect/configuration/configuration-v0/custom-full.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-simple-testnet-v0.tsx b/.snippets/code/products/connect/configuration/configuration-v0/custom-simple-testnet-v0.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-simple-testnet-v0.tsx rename to .snippets/code/products/connect/configuration/configuration-v0/custom-simple-testnet-v0.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-simple-v0.jsx b/.snippets/code/products/connect/configuration/configuration-v0/custom-simple-v0.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-simple-v0.jsx rename to .snippets/code/products/connect/configuration/configuration-v0/custom-simple-v0.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/index.ts b/.snippets/code/products/connect/configuration/configuration-v0/index.ts similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/index.ts rename to .snippets/code/products/connect/configuration/configuration-v0/index.ts diff --git a/.snippets/code/build/transfers/connect/configuration/sample-configuration.json b/.snippets/code/products/connect/configuration/configuration-v0/sample-configuration.json similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/sample-configuration.json rename to .snippets/code/products/connect/configuration/configuration-v0/sample-configuration.json diff --git a/.snippets/code/build/transfers/connect/configuration/add-token.tsx b/.snippets/code/products/connect/configuration/data/add-token.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/add-token.tsx rename to .snippets/code/products/connect/configuration/data/add-token.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/configure-hosted.tsx b/.snippets/code/products/connect/configuration/data/configure-hosted.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/configure-hosted.tsx rename to .snippets/code/products/connect/configuration/data/configure-hosted.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/configure-react-v1.tsx b/.snippets/code/products/connect/configuration/data/configure-react-v1.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/configure-react-v1.tsx rename to .snippets/code/products/connect/configuration/data/configure-react-v1.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-coingecko-key.jsx b/.snippets/code/products/connect/configuration/data/custom-coingecko-key.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-coingecko-key.jsx rename to .snippets/code/products/connect/configuration/data/custom-coingecko-key.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-disable-arbitrary-tokens.jsx b/.snippets/code/products/connect/configuration/data/custom-disable-arbitrary-tokens.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-disable-arbitrary-tokens.jsx rename to .snippets/code/products/connect/configuration/data/custom-disable-arbitrary-tokens.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-simple-testnet-v1.jsx b/.snippets/code/products/connect/configuration/data/custom-simple-testnet-v1.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-simple-testnet-v1.jsx rename to .snippets/code/products/connect/configuration/data/custom-simple-testnet-v1.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-simple-v1.jsx b/.snippets/code/products/connect/configuration/data/custom-simple-v1.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-simple-v1.jsx rename to .snippets/code/products/connect/configuration/data/custom-simple-v1.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-tokens-whitelist-advanced.jsx b/.snippets/code/products/connect/configuration/data/custom-tokens-whitelist-advanced.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-tokens-whitelist-advanced.jsx rename to .snippets/code/products/connect/configuration/data/custom-tokens-whitelist-advanced.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-tokens-whitelist.jsx b/.snippets/code/products/connect/configuration/data/custom-tokens-whitelist.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-tokens-whitelist.jsx rename to .snippets/code/products/connect/configuration/data/custom-tokens-whitelist.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-tx-settings-solana.jsx b/.snippets/code/products/connect/configuration/data/custom-tx-settings-solana.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-tx-settings-solana.jsx rename to .snippets/code/products/connect/configuration/data/custom-tx-settings-solana.jsx diff --git a/.snippets/code/build/transfers/connect/configuration/example-all-routes.ts b/.snippets/code/products/connect/configuration/data/example-all-routes.ts similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/example-all-routes.ts rename to .snippets/code/products/connect/configuration/data/example-all-routes.ts diff --git a/.snippets/code/build/transfers/connect/configuration/example-cctp.ts b/.snippets/code/products/connect/configuration/data/example-cctp.ts similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/example-cctp.ts rename to .snippets/code/products/connect/configuration/data/example-cctp.ts diff --git a/.snippets/code/products/connect/configuration/get-started/App.tsx b/.snippets/code/products/connect/configuration/get-started/App.tsx new file mode 100644 index 000000000..4740d2bad --- /dev/null +++ b/.snippets/code/products/connect/configuration/get-started/App.tsx @@ -0,0 +1,30 @@ +import './App.css'; +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; + +function App() { + const config: WormholeConnectConfig = { + // Define the network + network: 'Testnet', + + // Define the chains + chains: ['Sui', 'Avalanche'], + + // UI configuration + ui: { + title: 'SUI Connect TS Demo', + }, + }; + + const theme: WormholeConnectTheme = { + // Define the theme + mode: 'dark', + primary: '#78c4b6', + }; + + return ; +} + +export default App; diff --git a/.snippets/code/build/transfers/connect/configuration/custom-colors-hosted.tsx b/.snippets/code/products/connect/configuration/theme/custom-colors-hosted.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-colors-hosted.tsx rename to .snippets/code/products/connect/configuration/theme/custom-colors-hosted.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-colors.tsx b/.snippets/code/products/connect/configuration/theme/custom-colors.tsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-colors.tsx rename to .snippets/code/products/connect/configuration/theme/custom-colors.tsx diff --git a/.snippets/code/build/transfers/connect/configuration/custom-menu.jsx b/.snippets/code/products/connect/configuration/theme/custom-menu.jsx similarity index 100% rename from .snippets/code/build/transfers/connect/configuration/custom-menu.jsx rename to .snippets/code/products/connect/configuration/theme/custom-menu.jsx diff --git a/.snippets/code/build/transfers/connect/overview/hosted.js b/.snippets/code/products/connect/guides/hosted-version/hosted-1.js similarity index 72% rename from .snippets/code/build/transfers/connect/overview/hosted.js rename to .snippets/code/products/connect/guides/hosted-version/hosted-1.js index fda1ac369..4067feee6 100644 --- a/.snippets/code/build/transfers/connect/overview/hosted.js +++ b/.snippets/code/products/connect/guides/hosted-version/hosted-1.js @@ -2,5 +2,8 @@ import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; // Existing DOM element where you want to mount Connect const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'bridge-container' not found"); +} wormholeConnectHosted(container); diff --git a/.snippets/code/products/connect/guides/hosted-version/hosted-2.js b/.snippets/code/products/connect/guides/hosted-version/hosted-2.js new file mode 100644 index 000000000..5ec41ada8 --- /dev/null +++ b/.snippets/code/products/connect/guides/hosted-version/hosted-2.js @@ -0,0 +1,22 @@ +import { + wormholeConnectHosted, +} from '@wormhole-foundation/wormhole-connect'; + +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'connect' not found"); +} + +wormholeConnectHosted(container, { + config: { + rpcs: { + // ... + } + }, + theme: { + background: { + default: '#004547', + } + } +}); \ No newline at end of file diff --git a/.snippets/code/products/connect/tutorials/react-dapp/snippet-1.js b/.snippets/code/products/connect/tutorials/react-dapp/snippet-1.js new file mode 100644 index 000000000..f8f9397d4 --- /dev/null +++ b/.snippets/code/products/connect/tutorials/react-dapp/snippet-1.js @@ -0,0 +1,17 @@ +'use client'; + +import WormholeConnect from '@wormhole-foundation/wormhole-connect'; + +const config = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], +}; + +const theme = { + mode: 'light', + primary: '#78c4b6', +}; + +export default function Home() { + return ; +} diff --git a/.snippets/code/products/connect/tutorials/react-dapp/snippet-2.ts b/.snippets/code/products/connect/tutorials/react-dapp/snippet-2.ts new file mode 100644 index 000000000..a85b43b29 --- /dev/null +++ b/.snippets/code/products/connect/tutorials/react-dapp/snippet-2.ts @@ -0,0 +1,23 @@ +'use client'; + +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; + +export default function Home() { + const config: WormholeConnectConfig = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], + + ui: { + title: 'SUI Connect TS Demo', + }, + }; + + const theme: WormholeConnectTheme = { + mode: 'light', + primary: '#78c4b6', + }; + return ; +} diff --git a/.snippets/code/products/messaging/get-started/main.ts b/.snippets/code/products/messaging/get-started/main.ts new file mode 100644 index 000000000..d0fd1c804 --- /dev/null +++ b/.snippets/code/products/messaging/get-started/main.ts @@ -0,0 +1,183 @@ +import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } + + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); + + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); + + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; + + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); + + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); + + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} + +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); \ No newline at end of file diff --git a/.snippets/code/products/messaging/get-started/terminal01.html b/.snippets/code/products/messaging/get-started/terminal01.html new file mode 100644 index 000000000..5df2deba0 --- /dev/null +++ b/.snippets/code/products/messaging/get-started/terminal01.html @@ -0,0 +1,21 @@ +
+ npx tsx main.ts + Wormhole SDK Initialized. + Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 + Source chain context obtained for: Sepolia + Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 + Message to send: "HelloWormholeSDK-1748362375390" + Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... + Signing and sending the message publication transaction(s)... + Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 + View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 + Waiting a few seconds for transaction to propagate before parsing... + Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... + --- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 + ----------------------------------------- + +
\ No newline at end of file diff --git a/.snippets/code/build/core-messaging/core-contracts/receiveEmitterCheck.ts b/.snippets/code/products/messaging/guides/core-contracts/receiveEmitterCheck.ts similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/receiveEmitterCheck.ts rename to .snippets/code/products/messaging/guides/core-contracts/receiveEmitterCheck.ts diff --git a/.snippets/code/build/core-messaging/core-contracts/receiveMessageEVM.sol b/.snippets/code/products/messaging/guides/core-contracts/receiveMessageEVM.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/receiveMessageEVM.sol rename to .snippets/code/products/messaging/guides/core-contracts/receiveMessageEVM.sol diff --git a/.snippets/code/build/core-messaging/core-contracts/receiveMessageSolana.rs b/.snippets/code/products/messaging/guides/core-contracts/receiveMessageSolana.rs similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/receiveMessageSolana.rs rename to .snippets/code/products/messaging/guides/core-contracts/receiveMessageSolana.rs diff --git a/.snippets/code/build/core-messaging/core-contracts/receiving.sol b/.snippets/code/products/messaging/guides/core-contracts/receiving.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/receiving.sol rename to .snippets/code/products/messaging/guides/core-contracts/receiving.sol diff --git a/.snippets/code/build/core-messaging/core-contracts/sendMessageEVM.sol b/.snippets/code/products/messaging/guides/core-contracts/sendMessageEVM.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/sendMessageEVM.sol rename to .snippets/code/products/messaging/guides/core-contracts/sendMessageEVM.sol diff --git a/.snippets/code/build/core-messaging/core-contracts/sendMessageSolana.rs b/.snippets/code/products/messaging/guides/core-contracts/sendMessageSolana.rs similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/sendMessageSolana.rs rename to .snippets/code/products/messaging/guides/core-contracts/sendMessageSolana.rs diff --git a/.snippets/code/build/core-messaging/core-contracts/sending.sol b/.snippets/code/products/messaging/guides/core-contracts/sending.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/sending.sol rename to .snippets/code/products/messaging/guides/core-contracts/sending.sol diff --git a/.snippets/code/build/core-messaging/wormhole-relayers/ExampleContract.sol b/.snippets/code/products/messaging/guides/wormhole-relayers/ExampleContract.sol similarity index 100% rename from .snippets/code/build/core-messaging/wormhole-relayers/ExampleContract.sol rename to .snippets/code/products/messaging/guides/wormhole-relayers/ExampleContract.sol diff --git a/.snippets/code/build/core-messaging/wormhole-relayers/getQuoteAndSend.sol b/.snippets/code/products/messaging/guides/wormhole-relayers/getQuoteAndSend.sol similarity index 100% rename from .snippets/code/build/core-messaging/wormhole-relayers/getQuoteAndSend.sol rename to .snippets/code/products/messaging/guides/wormhole-relayers/getQuoteAndSend.sol diff --git a/.snippets/code/build/core-messaging/wormhole-relayers/quoteEVMDeliveryPrice.sol b/.snippets/code/products/messaging/guides/wormhole-relayers/quoteEVMDeliveryPrice.sol similarity index 100% rename from .snippets/code/build/core-messaging/wormhole-relayers/quoteEVMDeliveryPrice.sol rename to .snippets/code/products/messaging/guides/wormhole-relayers/quoteEVMDeliveryPrice.sol diff --git a/.snippets/code/build/core-messaging/wormhole-relayers/receiveWormholeMessages.sol b/.snippets/code/products/messaging/guides/wormhole-relayers/receiveWormholeMessages.sol similarity index 100% rename from .snippets/code/build/core-messaging/wormhole-relayers/receiveWormholeMessages.sol rename to .snippets/code/products/messaging/guides/wormhole-relayers/receiveWormholeMessages.sol diff --git a/.snippets/code/build/core-messaging/wormhole-relayers/sendPayloadToEvm.sol b/.snippets/code/products/messaging/guides/wormhole-relayers/sendPayloadToEvm.sol similarity index 100% rename from .snippets/code/build/core-messaging/wormhole-relayers/sendPayloadToEvm.sol rename to .snippets/code/products/messaging/guides/wormhole-relayers/sendPayloadToEvm.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-1.sol b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-1.sol similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-1.sol rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-1.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-4.html b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-4.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-4.html rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-4.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-7.html b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-7.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-7.html rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-7.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-8.html b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-8.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-8.html rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-8.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-9.json b/.snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-9.json similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-contracts/snippet-9.json rename to .snippets/code/products/messaging/tutorials/cross-chain-contracts/snippet-9.json diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-10.html b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-10.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-10.html rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-10.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-11.sol b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-11.sol similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-11.sol rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-11.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-3.json b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-3.json similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-3.json rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-3.json diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-6.html b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-6.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-6.html rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-6.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-7.html b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-7.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-7.html rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-7.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-8.html b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-8.html similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-8.html rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-8.html diff --git a/.snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-9.json b/.snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-9.json similarity index 100% rename from .snippets/code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-9.json rename to .snippets/code/products/messaging/tutorials/cross-chain-token-transfers/snippet-9.json diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-1.json b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-1.json similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-1.json rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-1.json diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-10.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-10.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-10.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-10.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-11.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-11.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-11.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-11.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-12.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-12.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-12.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-12.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-13.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-13.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-13.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-13.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-14.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-14.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-14.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-14.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-15.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-15.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-15.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-15.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-16.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-16.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-16.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-16.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-17.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-17.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-17.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-17.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-2.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-2.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-2.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-2.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-3.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-3.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-3.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-3.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-5.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-5.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-5.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-5.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-6.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-6.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-6.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-6.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-7.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-7.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-7.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-7.ts diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-8.html b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-8.html similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-8.html rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-8.html diff --git a/.snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-9.ts b/.snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-9.ts similarity index 100% rename from .snippets/code/tutorials/wormholescan/replace-signatures/replace-sigs-9.ts rename to .snippets/code/products/messaging/tutorials/replace-signatures/replace-sigs-9.ts diff --git a/.snippets/code/build/transfers/native-token-transfers/deployment-process/INttToken.sol b/.snippets/code/products/native-token-transfers/guides/deploy-to-evm/INttToken.sol similarity index 100% rename from .snippets/code/build/transfers/native-token-transfers/deployment-process/INttToken.sol rename to .snippets/code/products/native-token-transfers/guides/deploy-to-evm/INttToken.sol diff --git a/.snippets/code/build/transfers/native-token-transfers/deployment-process/initialize.txt b/.snippets/code/products/native-token-transfers/guides/deploy-to-evm/initialize.txt similarity index 100% rename from .snippets/code/build/transfers/native-token-transfers/deployment-process/initialize.txt rename to .snippets/code/products/native-token-transfers/guides/deploy-to-evm/initialize.txt diff --git a/.snippets/code/products/queries/get-started/snippet-1.ts b/.snippets/code/products/queries/get-started/snippet-1.ts new file mode 100644 index 000000000..ef24d019b --- /dev/null +++ b/.snippets/code/products/queries/get-started/snippet-1.ts @@ -0,0 +1,60 @@ +// Import the SDK types and helpers for making the query +import { + EthCallQueryRequest, + EthCallQueryResponse, + PerChainQueryRequest, + QueryRequest, + QueryResponse, +} from '@wormhole-foundation/wormhole-query-sdk'; +import axios from 'axios'; +import * as eth from 'web3'; + +// Define the endpoint and query parameters +const query_url = 'https://testnet.query.wormhole.com/v1/query'; +const rpc = 'https://ethereum-sepolia.rpc.subquery.network/public'; +const chain_id = 10002; // Sepolia (Wormhole chain ID) +const token = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'; // USDC contract +const data = '0x06fdde03'; // function selector for `name()` + +// Load your API key from environment variables +const apiKey = process.env.API_KEY; +if (!apiKey) throw new Error('API_KEY is not set in your environment'); + +(async () => { + // Fetch the latest block number (required to anchor the query) + const latestBlock = ( + await axios.post(rpc, { + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 1, + jsonrpc: '2.0', + }) + ).data?.result?.number; + + // Build the query targeting the token contract's name() function + const request = new QueryRequest(1, [ + new PerChainQueryRequest( + chain_id, + new EthCallQueryRequest(latestBlock, [{ to: token, data: data }]) + ), + ]); + const serialized = request.serialize(); + + // Send the query to the Wormhole Query Proxy + const response = await axios.post( + query_url, + { bytes: Buffer.from(serialized).toString('hex') }, + { headers: { 'X-API-Key': apiKey } } + ); + + // Decode the response returned by the Guardian network + const queryResponse = QueryResponse.from(response.data.bytes); + const chainResponse = queryResponse.responses[0] + .response as EthCallQueryResponse; + const name = eth.eth.abi.decodeParameter('string', chainResponse.results[0]); + + // Output the results + console.log('\n\nParsed chain response:'); + console.log(chainResponse); + console.log('\nToken name:', name); +})(); diff --git a/.snippets/code/products/queries/get-started/snippet-2.html b/.snippets/code/products/queries/get-started/snippet-2.html new file mode 100644 index 000000000..b25cede17 --- /dev/null +++ b/.snippets/code/products/queries/get-started/snippet-2.html @@ -0,0 +1,13 @@ +
+ API_KEY=123_456_789 npx tsx query.ts + Parsed chain response: + EthCallQueryResponse { + blockNumber: 8193548n, + blockHash: '0xef97290e043a530dd2cdf2d4c513397495029cdf2ef3e916746c837dadda51a8', + blockTime: 1745595132000000n, + results: [ '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000'] + } + + Token name: USDC + +
diff --git a/.snippets/code/build/queries/use-queries/eth-call-initial-request.txt b/.snippets/code/products/queries/guides/use-queries/eth-call-initial-request.txt similarity index 100% rename from .snippets/code/build/queries/use-queries/eth-call-initial-request.txt rename to .snippets/code/products/queries/guides/use-queries/eth-call-initial-request.txt diff --git a/.snippets/code/build/queries/use-queries/eth-call-initial-response.txt b/.snippets/code/products/queries/guides/use-queries/eth-call-initial-response.txt similarity index 100% rename from .snippets/code/build/queries/use-queries/eth-call-initial-response.txt rename to .snippets/code/products/queries/guides/use-queries/eth-call-initial-response.txt diff --git a/.snippets/code/build/queries/use-queries/query-demo.sol b/.snippets/code/products/queries/guides/use-queries/query-demo.sol similarity index 100% rename from .snippets/code/build/queries/use-queries/query-demo.sol rename to .snippets/code/products/queries/guides/use-queries/query-demo.sol diff --git a/.snippets/code/build/queries/use-queries/query-proxy-query-response.jsx b/.snippets/code/products/queries/guides/use-queries/query-proxy-query-response.jsx similarity index 97% rename from .snippets/code/build/queries/use-queries/query-proxy-query-response.jsx rename to .snippets/code/products/queries/guides/use-queries/query-proxy-query-response.jsx index ab1612093..1a9031af3 100644 --- a/.snippets/code/build/queries/use-queries/query-proxy-query-response.jsx +++ b/.snippets/code/products/queries/guides/use-queries/query-proxy-query-response.jsx @@ -1,4 +1,4 @@ const tx = await contract.updateCounters( `0x${response.data.bytes}`, signaturesToEvmStruct(response.data.signatures) -); \ No newline at end of file +); diff --git a/.snippets/code/products/queries/guides/use-queries/query-request-with-api-key.jsx b/.snippets/code/products/queries/guides/use-queries/query-request-with-api-key.jsx new file mode 100644 index 000000000..15fcfe954 --- /dev/null +++ b/.snippets/code/products/queries/guides/use-queries/query-request-with-api-key.jsx @@ -0,0 +1,9 @@ +const serialized = request.serialize(); +const proxyResponse = + (await axios.post) < + QueryProxyQueryResponse > + (QUERY_URL, + { + bytes: Buffer.from(serialized).toString("hex"), + }, + { headers: { "X-API-Key": YOUR_API_KEY } }); diff --git a/.snippets/code/build/queries/use-queries/test-full.jsx b/.snippets/code/products/queries/guides/use-queries/test-full.jsx similarity index 100% rename from .snippets/code/build/queries/use-queries/test-full.jsx rename to .snippets/code/products/queries/guides/use-queries/test-full.jsx diff --git a/.snippets/code/build/reference/formatted-addresses/evm.ts b/.snippets/code/products/reference/formatted-addresses/evm.ts similarity index 100% rename from .snippets/code/build/reference/formatted-addresses/evm.ts rename to .snippets/code/products/reference/formatted-addresses/evm.ts diff --git a/.snippets/code/build/reference/formatted-addresses/solana.ts b/.snippets/code/products/reference/formatted-addresses/solana.ts similarity index 100% rename from .snippets/code/build/reference/formatted-addresses/solana.ts rename to .snippets/code/products/reference/formatted-addresses/solana.ts diff --git a/.snippets/code/products/settlement/get-started/snippet-1.ts b/.snippets/code/products/settlement/get-started/snippet-1.ts new file mode 100644 index 000000000..2815dc1fa --- /dev/null +++ b/.snippets/code/products/settlement/get-started/snippet-1.ts @@ -0,0 +1,50 @@ +import { + Chain, + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, +} from '@wormhole-foundation/sdk-connect'; +import { getEvmSignerForKey } from '@wormhole-foundation/sdk-evm'; +import { getSolanaSigner } from '@wormhole-foundation/sdk-solana'; + +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (MAINNET_ETH_PRIVATE_KEY, MAINNET_SOL_PRIVATE_KEY) + * must be loaded securely beforehand, for example via a keystore, + * secrets manager, or environment variables (not recommended). + */ +// Define Transfer Interface +export interface SignerContext { + signer: Signer; + address: ChainAddress; +} + +export async function getSigner( + chain: ChainContext +): Promise> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + switch (platform) { + case 'Solana': + signer = await getSolanaSigner( + await chain.getRpc(), + getEnv('MAINNET_SOL_PRIVATE_KEY') + ); + break; + case 'Evm': + signer = await getEvmSignerForKey( + await chain.getRpc(), + getEnv('MAINNET_ETH_PRIVATE_KEY') + ); + break; + default: + throw new Error('Unrecognized platform: ' + platform); + } + + return { + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} diff --git a/.snippets/code/products/settlement/get-started/snippet-2.ts b/.snippets/code/products/settlement/get-started/snippet-2.ts new file mode 100644 index 000000000..e4d7cfeac --- /dev/null +++ b/.snippets/code/products/settlement/get-started/snippet-2.ts @@ -0,0 +1,82 @@ +import { Wormhole, routes } from '@wormhole-foundation/sdk-connect'; +import { EvmPlatform } from '@wormhole-foundation/sdk-evm'; +import { SolanaPlatform } from '@wormhole-foundation/sdk-solana'; +import { MayanRouteSWIFT } from '@mayanfinance/wormhole-sdk-route'; +import { getSigner } from './helpers'; + +(async function () { + // Setup + const wh = new Wormhole('Mainnet', [EvmPlatform, SolanaPlatform]); + + const sendChain = wh.getChain('Ethereum'); + const destChain = wh.getChain('Solana'); + + // To transfer native ETH on Ethereum to native SOL on Solana + const source = Wormhole.tokenId(sendChain.chain, 'native'); + const destination = Wormhole.tokenId(destChain.chain, 'native'); + + // Create a new Wormhole route resolver, adding the Mayan route to the default list + // @ts-ignore: Suppressing TypeScript error because the resolver method expects a specific type, + // but MayanRouteSWIFT is compatible and works as intended in this context. + const resolver = wh.resolver([MayanRouteSWIFT]); + + // Show supported tokens + const dstTokens = await resolver.supportedDestinationTokens( + source, + sendChain, + destChain + ); + console.log(dstTokens.slice(0, 5)); + + // Load signers and addresses from helpers + const sender = await getSigner(sendChain); + const receiver = await getSigner(destChain); + + // Creating a transfer request fetches token details + // since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source, + destination, + }); + + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + const bestRoute = foundRoutes[0]!; + + // Specify the amount as a decimal string + const transferParams = { + amount: '0.002', + options: bestRoute.getDefaultOptions(), + }; + + // Validate the queries route + let validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) { + console.error(validated.error); + return; + } + console.log('Validated: ', validated); + + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) { + console.error(`Error fetching a quote: ${quote.error.message}`); + return; + } + console.log('Quote: ', quote); + + // Initiate the transfer + const receipt = await bestRoute.initiate( + tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); + + await routes.checkAndCompleteTransfer( + bestRoute, + receipt, + receiver.signer, + 15 * 60 * 1000 + ); +})(); diff --git a/.snippets/code/products/settlement/get-started/snippet-3.html b/.snippets/code/products/settlement/get-started/snippet-3.html new file mode 100644 index 000000000..718db10f3 --- /dev/null +++ b/.snippets/code/products/settlement/get-started/snippet-3.html @@ -0,0 +1,13 @@ +
+ npx tsx src/swap.ts + Validated: { valid: true, ... } + Quote: { success: true, ... } + Initiated transfer with receipt: ... + Checking transfer state... + Current Transfer State: SourceInitiated + Current Transfer State: SourceInitiated + Current Transfer State: SourceInitiated + Current Transfer State: DestinationFinalized + +
+ diff --git a/.snippets/code/build/transfers/settlement/placeFastMarketOrder.sol b/.snippets/code/products/settlement/guides/liquidity-layer/placeFastMarketOrder.sol similarity index 100% rename from .snippets/code/build/transfers/settlement/placeFastMarketOrder.sol rename to .snippets/code/products/settlement/guides/liquidity-layer/placeFastMarketOrder.sol diff --git a/.snippets/code/build/transfers/settlement/placeMarketOrder.sol b/.snippets/code/products/settlement/guides/liquidity-layer/placeMarketOrder.sol similarity index 100% rename from .snippets/code/build/transfers/settlement/placeMarketOrder.sol rename to .snippets/code/products/settlement/guides/liquidity-layer/placeMarketOrder.sol diff --git a/.snippets/code/build/transfers/settlement/solver-config.json b/.snippets/code/products/settlement/guides/solver/solver-config.json similarity index 100% rename from .snippets/code/build/transfers/settlement/solver-config.json rename to .snippets/code/products/settlement/guides/solver/solver-config.json diff --git a/.snippets/code/products/token-bridge/get-started/snippet-1.ts b/.snippets/code/products/token-bridge/get-started/snippet-1.ts new file mode 100644 index 000000000..ff4f5d7e4 --- /dev/null +++ b/.snippets/code/products/token-bridge/get-started/snippet-1.ts @@ -0,0 +1,70 @@ +import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, + isTokenId, + TokenId, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; + +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } + + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + +/** + * Get the number of decimals for the token on the source chain. + * This helps convert a user-friendly amount (e.g., '1') into raw units. + */ +export async function getTokenDecimals( + wh: Wormhole, + token: TokenId, + chain: ChainContext +): Promise { + return isTokenId(token) + ? Number(await wh.getDecimals(token.chain, token.address)) + : chain.config.nativeTokenDecimals; +} diff --git a/.snippets/code/products/token-bridge/get-started/snippet-2.ts b/.snippets/code/products/token-bridge/get-started/snippet-2.ts new file mode 100644 index 000000000..10e2e3c52 --- /dev/null +++ b/.snippets/code/products/token-bridge/get-started/snippet-2.ts @@ -0,0 +1,58 @@ +import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; + +(async function () { + // Initialize Wormhole SDK for Solana and Sepolia on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); + + // Define the source and destination chains + const sendChain = wh.getChain('Solana'); + const rcvChain = wh.getChain('Sepolia'); + + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Solana', 'native'); + const amt = '0.1'; + + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); + + // Set to false to require manual approval steps + const automatic = false; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); + + // Initiate the transfer from Solana + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + // Wait for the signed attestation from the Guardian network + console.log('Fetching Attestation'); + const timeout = 5 * 60 * 1000; // 5 minutes + await xfer.fetchAttestation(timeout); + + // Redeem the tokens on Sepolia + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, destTxids); + + process.exit(0); +})(); diff --git a/.snippets/code/products/token-bridge/get-started/snippet-3.ts b/.snippets/code/products/token-bridge/get-started/snippet-3.ts new file mode 100644 index 000000000..f4e3f3953 --- /dev/null +++ b/.snippets/code/products/token-bridge/get-started/snippet-3.ts @@ -0,0 +1,48 @@ +import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; + +(async function () { + // Initialize Wormhole SDK for Avalanche and Celo on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); + + // Define the source and destination chains + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Celo'); + + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Avalanche', 'native'); + const amt = '0.2'; + + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); + + // Set to false to require manual approval steps + const automatic = true; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); + + // Initiate the transfer from Avalanche Fuji + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + process.exit(0); +})(); diff --git a/.snippets/code/products/token-bridge/get-started/snippet-4.html b/.snippets/code/products/token-bridge/get-started/snippet-4.html new file mode 100644 index 000000000..a7706f0ee --- /dev/null +++ b/.snippets/code/products/token-bridge/get-started/snippet-4.html @@ -0,0 +1,14 @@ +
+ npx tsx transfer.ts + Starting Transfer + Started Transfer: ['36UwBBh6HH6wt3VBbNNawMd1ijCk28YgFePrBWfE3vGQFHtbMjY5626nqHubmyQWGNh2ZrN1vHKRrSQDNC3gkZgB'] + + Getting Attestation + Retrying Wormholescan:GetVaaBytes, attempt 0/900 + Retrying Wormholescan:GetVaaBytes, attempt 1/900 + Retrying Wormholescan:GetVaaBytes, attempt 2/900 + + Completing Transfer + Completed Transfer: [ '53Nt4mp2KRTk2HFyvUcmP9b6cRXjVAN3wCksoBey9WmT' ] + +
\ No newline at end of file diff --git a/.snippets/code/build/core-messaging/core-contracts/attestToken.sol b/.snippets/code/products/token-bridge/guides/token-bridge-contracts/attestToken.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/attestToken.sol rename to .snippets/code/products/token-bridge/guides/token-bridge-contracts/attestToken.sol diff --git a/.snippets/code/build/core-messaging/core-contracts/transferTokens.sol b/.snippets/code/products/token-bridge/guides/token-bridge-contracts/transferTokens.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/transferTokens.sol rename to .snippets/code/products/token-bridge/guides/token-bridge-contracts/transferTokens.sol diff --git a/.snippets/code/build/core-messaging/core-contracts/transferTokensWithPayload.sol b/.snippets/code/products/token-bridge/guides/token-bridge-contracts/transferTokensWithPayload.sol similarity index 100% rename from .snippets/code/build/core-messaging/core-contracts/transferTokensWithPayload.sol rename to .snippets/code/products/token-bridge/guides/token-bridge-contracts/transferTokensWithPayload.sol diff --git a/.snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-1.ts b/.snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-1.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-1.ts rename to .snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-1.ts diff --git a/.snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts b/.snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts rename to .snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts diff --git a/.snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts b/.snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts similarity index 100% rename from .snippets/code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts rename to .snippets/code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-1.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-1.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-1.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-1.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-2.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-2.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-2.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-2.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-3.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-3.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-3.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-3.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-4.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-4.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-4.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-4.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-5.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-5.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-5.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-5.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-6.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-6.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-6.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-6.ts diff --git a/.snippets/code/build/infrastructure/relayers/run-relayer/snippet-7.ts b/.snippets/code/protocol/infrastructure-guides/run-relayer/snippet-7.ts similarity index 100% rename from .snippets/code/build/infrastructure/relayers/run-relayer/snippet-7.ts rename to .snippets/code/protocol/infrastructure-guides/run-relayer/snippet-7.ts diff --git a/.snippets/code/learn/infrastructure/VAAs/snippet-1.js b/.snippets/code/protocol/infrastructure/VAAs/snippet-1.js similarity index 100% rename from .snippets/code/learn/infrastructure/VAAs/snippet-1.js rename to .snippets/code/protocol/infrastructure/VAAs/snippet-1.js diff --git a/.snippets/code/learn/infrastructure/VAAs/snippet-2.js b/.snippets/code/protocol/infrastructure/VAAs/snippet-2.js similarity index 100% rename from .snippets/code/learn/infrastructure/VAAs/snippet-2.js rename to .snippets/code/protocol/infrastructure/VAAs/snippet-2.js diff --git a/.snippets/code/build/toolkit/cli/aptos.txt b/.snippets/code/tools/cli/get-started/aptos.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/aptos.txt rename to .snippets/code/tools/cli/get-started/aptos.txt diff --git a/.snippets/code/build/toolkit/cli/edit-vaa.txt b/.snippets/code/tools/cli/get-started/edit-vaa.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/edit-vaa.txt rename to .snippets/code/tools/cli/get-started/edit-vaa.txt diff --git a/.snippets/code/build/toolkit/cli/evm.txt b/.snippets/code/tools/cli/get-started/evm.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/evm.txt rename to .snippets/code/tools/cli/get-started/evm.txt diff --git a/.snippets/code/build/toolkit/cli/fetch-vaa-example.txt b/.snippets/code/tools/cli/get-started/fetch-vaa-example.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/fetch-vaa-example.txt rename to .snippets/code/tools/cli/get-started/fetch-vaa-example.txt diff --git a/.snippets/code/build/toolkit/cli/generate.txt b/.snippets/code/tools/cli/get-started/generate.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/generate.txt rename to .snippets/code/tools/cli/get-started/generate.txt diff --git a/.snippets/code/build/toolkit/cli/guardian-upgrade.txt b/.snippets/code/tools/cli/get-started/guardian-upgrade.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/guardian-upgrade.txt rename to .snippets/code/tools/cli/get-started/guardian-upgrade.txt diff --git a/.snippets/code/build/toolkit/cli/info-response.txt b/.snippets/code/tools/cli/get-started/info-response.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/info-response.txt rename to .snippets/code/tools/cli/get-started/info-response.txt diff --git a/.snippets/code/build/toolkit/cli/info.txt b/.snippets/code/tools/cli/get-started/info.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/info.txt rename to .snippets/code/tools/cli/get-started/info.txt diff --git a/.snippets/code/build/toolkit/cli/near.txt b/.snippets/code/tools/cli/get-started/near.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/near.txt rename to .snippets/code/tools/cli/get-started/near.txt diff --git a/.snippets/code/build/toolkit/cli/parse.txt b/.snippets/code/tools/cli/get-started/parse.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/parse.txt rename to .snippets/code/tools/cli/get-started/parse.txt diff --git a/.snippets/code/build/toolkit/cli/recover.txt b/.snippets/code/tools/cli/get-started/recover.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/recover.txt rename to .snippets/code/tools/cli/get-started/recover.txt diff --git a/.snippets/code/build/toolkit/cli/status.txt b/.snippets/code/tools/cli/get-started/status.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/status.txt rename to .snippets/code/tools/cli/get-started/status.txt diff --git a/.snippets/code/build/toolkit/cli/submit.txt b/.snippets/code/tools/cli/get-started/submit.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/submit.txt rename to .snippets/code/tools/cli/get-started/submit.txt diff --git a/.snippets/code/build/toolkit/cli/sui.txt b/.snippets/code/tools/cli/get-started/sui.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/sui.txt rename to .snippets/code/tools/cli/get-started/sui.txt diff --git a/.snippets/code/build/toolkit/cli/token-attestation-vaa.txt b/.snippets/code/tools/cli/get-started/token-attestation-vaa.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/token-attestation-vaa.txt rename to .snippets/code/tools/cli/get-started/token-attestation-vaa.txt diff --git a/.snippets/code/build/toolkit/cli/transfer.txt b/.snippets/code/tools/cli/get-started/transfer.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/transfer.txt rename to .snippets/code/tools/cli/get-started/transfer.txt diff --git a/.snippets/code/build/toolkit/cli/vaa-generation-example.txt b/.snippets/code/tools/cli/get-started/vaa-generation-example.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/vaa-generation-example.txt rename to .snippets/code/tools/cli/get-started/vaa-generation-example.txt diff --git a/.snippets/code/build/toolkit/cli/verify-vaa.txt b/.snippets/code/tools/cli/get-started/verify-vaa.txt similarity index 100% rename from .snippets/code/build/toolkit/cli/verify-vaa.txt rename to .snippets/code/tools/cli/get-started/verify-vaa.txt diff --git a/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-1.sol b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-1.sol new file mode 100644 index 000000000..c8f38ed10 --- /dev/null +++ b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-1.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } + + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} diff --git a/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-2.sol b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-2.sol new file mode 100644 index 000000000..9e5fb77bd --- /dev/null +++ b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-2.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} diff --git a/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-3.ts b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-3.ts new file mode 100644 index 000000000..5bffb4e34 --- /dev/null +++ b/.snippets/code/tools/solidity-sdk/get-started/solidity-sdk-3.ts @@ -0,0 +1,140 @@ +import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); + +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } + + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } + + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); + + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; + + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); + + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); + + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); + + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); + + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); diff --git a/.snippets/code/tools/solidity-sdk/get-started/terminal-output-01.html b/.snippets/code/tools/solidity-sdk/get-started/terminal-output-01.html new file mode 100644 index 000000000..5e1a8e5d7 --- /dev/null +++ b/.snippets/code/tools/solidity-sdk/get-started/terminal-output-01.html @@ -0,0 +1,10 @@ +
+ npx tsx script/transfer.ts + Initializing Wormhole SDK... + Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 + Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 + Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... + Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 + ✅ Transfer initiated successfully! + +
\ No newline at end of file diff --git a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-1.sol b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-1.sol similarity index 90% rename from .snippets/code/build/toolkit/solidity-sdk/solidity-sdk-1.sol rename to .snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-1.sol index 5e4b361f9..2293c104c 100644 --- a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-1.sol +++ b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-1.sol @@ -9,4 +9,4 @@ import "wormhole-sdk/Utils.sol"; import {Base} from "wormhole-sdk/WormholeRelayer/Base.sol"; import {TokenBase, TokenReceiver, TokenSender} from "wormhole-sdk/WormholeRelayer/TokenBase.sol"; import {CCTPBase, CCTPReceiver, CCTPSender} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; -import {CCTPAndTokenBase, CCTPAndTokenReceiver, CCTPAndTokenSender} from "wormhole-sdk/WormholeRelayer/CCTPAndTokenBase.sol"; +import {CCTPAndTokenBase, CCTPAndTokenReceiver, CCTPAndTokenSender} from "wormhole-sdk/WormholeRelayer/CCTPAndTokenBase.sol"; \ No newline at end of file diff --git a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-2.sol b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-2.sol similarity index 99% rename from .snippets/code/build/toolkit/solidity-sdk/solidity-sdk-2.sol rename to .snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-2.sol index 7c54b6ba9..03beddc4e 100644 --- a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-2.sol +++ b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-2.sol @@ -52,4 +52,4 @@ abstract contract Base { ); registeredSenders[sourceChain] = sourceAddress; } -} +} \ No newline at end of file diff --git a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-3.sol b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-3.sol similarity index 99% rename from .snippets/code/build/toolkit/solidity-sdk/solidity-sdk-3.sol rename to .snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-3.sol index 7b6bcebac..ff3994ebf 100644 --- a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-3.sol +++ b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-3.sol @@ -23,4 +23,4 @@ contract CrossChainSender is Base { 500_000 ); } -} +} \ No newline at end of file diff --git a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-4.sol b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-4.sol similarity index 99% rename from .snippets/code/build/toolkit/solidity-sdk/solidity-sdk-4.sol rename to .snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-4.sol index c8344a06b..dcf9c43c5 100644 --- a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-4.sol +++ b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-4.sol @@ -17,4 +17,4 @@ contract CrossChainTokenSender is TokenSender { // Send tokens across chains transferTokenToTarget(token, amount, targetChain, targetAddress); } -} +} \ No newline at end of file diff --git a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-5.sol b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-5.sol similarity index 99% rename from .snippets/code/build/toolkit/solidity-sdk/solidity-sdk-5.sol rename to .snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-5.sol index fd9c5a744..a0bc97d14 100644 --- a/.snippets/code/build/toolkit/solidity-sdk/solidity-sdk-5.sol +++ b/.snippets/code/tools/solidity-sdk/sdk-reference/solidity-sdk-5.sol @@ -19,4 +19,4 @@ contract CrossChainTokenReceiver is TokenReceiver { // Process the received tokens here receiveTokens(payload); } -} +} \ No newline at end of file diff --git a/.snippets/code/tools/typescript-sdk/get-started/snippet-1.ts b/.snippets/code/tools/typescript-sdk/get-started/snippet-1.ts new file mode 100644 index 000000000..4703fc99c --- /dev/null +++ b/.snippets/code/tools/typescript-sdk/get-started/snippet-1.ts @@ -0,0 +1,21 @@ +import { wormhole } from '@wormhole-foundation/sdk'; +// Import specific platform modules for the chains you intend to use +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; + +async function main() { + console.log('Initializing Wormhole SDK...'); + + // Determine the network: "Mainnet", "Testnet", or "Devnet" + const network = 'Testnet'; + + // Initialize the SDK with the chosen network and platform contexts + const wh = await wormhole(network, [evm, solana]); + + console.log('Wormhole SDK Initialized!'); +} + +main().catch((e) => { + console.error('Error initializing Wormhole SDK', e); + process.exit(1); +}); diff --git a/.snippets/code/tools/typescript-sdk/get-started/snippet-2.ts b/.snippets/code/tools/typescript-sdk/get-started/snippet-2.ts new file mode 100644 index 000000000..1e5f79878 --- /dev/null +++ b/.snippets/code/tools/typescript-sdk/get-started/snippet-2.ts @@ -0,0 +1,32 @@ +import { wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; + +async function main() { + console.log('Initializing Wormhole SDK...'); + + const network = 'Testnet'; + const wh = await wormhole(network, [evm, solana]); + + console.log('Wormhole SDK Initialized!'); + + // Example: Get a chain ID and RPC for Solana + const solanaDevnetChain = wh.getChain('Solana'); + console.log( + `Chain ID for Solana Testnet: ${solanaDevnetChain.config.chainId}` + ); + console.log(`RPC for Solana Testnet: ${solanaDevnetChain.config.rpc}`); + + // Example: Get a chain ID for Sepolia (EVM Testnet) + const sepoliaChain = wh.getChain('Sepolia'); + console.log(`Chain ID for Sepolia: ${sepoliaChain.config.chainId}`); + console.log(`RPC for Sepolia: ${sepoliaChain.config.rpc}`); +} + +main().catch((e) => { + console.error( + 'Error initializing Wormhole SDK or fetching chain information:', + e + ); + process.exit(1); +}); diff --git a/.snippets/code/tools/typescript-sdk/get-started/terminal-01.html b/.snippets/code/tools/typescript-sdk/get-started/terminal-01.html new file mode 100644 index 000000000..d7d0455a6 --- /dev/null +++ b/.snippets/code/tools/typescript-sdk/get-started/terminal-01.html @@ -0,0 +1,12 @@ +
+ npx tsx src/main.ts + Initializing Wormhole SDK... + Wormhole SDK Initialized! + Chain ID for Solana Testnet: 1 + RPC for Solana Testnet: https://api.devnet.solana.com + Chain ID for Sepolia: 10002 + RPC for Sepolia: https://ethereum-sepolia.publicnode.com + +
\ No newline at end of file diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-1.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-1.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-1.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-1.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-2.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-2.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-2.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-2.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-3.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-3.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-3.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-3.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-4.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-4.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-4.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-4.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-5.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-5.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-5.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-5.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-6.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-6.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-6.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-6.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-7.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-7.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-7.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-7.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-8.ts b/.snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-8.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/protocols-payloads/pl-8.ts rename to .snippets/code/tools/typescript-sdk/guides/protocols-payloads/pl-8.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-0.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-0.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-0.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-0.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-1.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-1.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-1.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-1.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-10.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-10.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-10.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-10.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-11.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-11.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-11.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-11.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-12.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-12.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-12.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-12.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-13.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-13.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-13.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-13.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-14.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-14.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-14.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-14.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-15.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-15.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-15.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-15.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-16.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-16.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-16.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-16.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-17.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-17.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-17.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-17.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-18.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-18.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-18.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-18.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-19.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-19.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-19.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-19.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-2.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-2.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-2.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-2.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-20.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-20.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-20.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-20.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-21.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-21.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-21.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-21.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-22.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-22.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-22.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-22.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-23.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-23.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-23.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-23.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-25.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-25.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-25.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-25.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-26.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-26.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-26.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-26.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-27.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-27.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-27.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-27.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-3.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-3.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-3.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-3.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-4.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-4.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-4.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-4.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-5.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-5.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-5.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-5.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-6.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-6.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-6.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-6.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-7.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-7.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-7.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-7.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-8.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-8.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-8.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-8.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-9.ts b/.snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-9.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/sdk-layout/layout-9.ts rename to .snippets/code/tools/typescript-sdk/guides/sdk-layout/layout-9.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/vaas-protocols/solidity-sdk.sol b/.snippets/code/tools/typescript-sdk/guides/vaas-protocols/solidity-sdk.sol similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/vaas-protocols/solidity-sdk.sol rename to .snippets/code/tools/typescript-sdk/guides/vaas-protocols/solidity-sdk.sol diff --git a/.snippets/code/build/toolkit/typescript-sdk/vaas-protocols/ts-sdk.ts b/.snippets/code/tools/typescript-sdk/guides/vaas-protocols/ts-sdk.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/vaas-protocols/ts-sdk.ts rename to .snippets/code/tools/typescript-sdk/guides/vaas-protocols/ts-sdk.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/addresses.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/addresses.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/addresses.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/addresses.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/cctp.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/cctp.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/cctp.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/cctp.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/config-override.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/config-override.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/config-override.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/config-override.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/config.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/config.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/config.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/config.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/custom-route.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/custom-route.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/custom-route.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/custom-route.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/ethers.js b/.snippets/code/tools/typescript-sdk/sdk-reference/ethers.js similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/ethers.js rename to .snippets/code/tools/typescript-sdk/sdk-reference/ethers.js diff --git a/.snippets/code/build/toolkit/typescript-sdk/example-core-bridge.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/example-core-bridge.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/example-core-bridge.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/example-core-bridge.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/get-chain.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/get-chain.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/get-chain.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/get-chain.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/get-vaa.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/get-vaa.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/get-vaa.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/get-vaa.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/router.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/router.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/router.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/router.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/signers.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/signers.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/signers.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/signers.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/token-bridge-snippet.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/token-bridge-snippet.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/token-bridge-snippet.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/token-bridge-snippet.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/token-bridge.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/token-bridge.ts similarity index 100% rename from .snippets/code/build/toolkit/typescript-sdk/token-bridge.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/token-bridge.ts diff --git a/.snippets/code/build/toolkit/typescript-sdk/tokens.ts b/.snippets/code/tools/typescript-sdk/sdk-reference/tokens.ts similarity index 66% rename from .snippets/code/build/toolkit/typescript-sdk/tokens.ts rename to .snippets/code/tools/typescript-sdk/sdk-reference/tokens.ts index 4298b7020..362668b6a 100644 --- a/.snippets/code/build/toolkit/typescript-sdk/tokens.ts +++ b/.snippets/code/tools/typescript-sdk/sdk-reference/tokens.ts @@ -1,5 +1,6 @@ +// Get the TokenId for an ERC-20 token const sourceToken: TokenId = Wormhole.tokenId('Ethereum', '0xbeef...'); - +// Get the TokenId for native ETH const gasToken: TokenId = Wormhole.tokenId('Ethereum', 'native'); - +// Convert a TokenId back to a string const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' \ No newline at end of file diff --git a/.snippets/text/build/core-messaging/core-messaging-timeline.json b/.snippets/text/build/core-messaging/core-messaging-timeline.json deleted file mode 100644 index e583898c3..000000000 --- a/.snippets/text/build/core-messaging/core-messaging-timeline.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "title": "[Send Messages](/docs/build/core-messaging/core-contracts/#sending-messages)", - "content": "How-to send messages with Core Contracts.", - "icon": ":fontawesome-solid-1:" - }, - { - "title": "[Interact with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/#receive-a-message)", - "content": "How-to use Wormhole Relayer in your messaging workflow.", - "icon": ":fontawesome-solid-2:" - }, - { - "title": "[Receive Messages](/docs/build/core-messaging/core-contracts/#receiving-messages)", - "content": "How-to verify and parse received messages.", - "icon": ":fontawesome-solid-3:" - }, - { - "title": "[Validate the Emitter](/docs/build/core-messaging/core-contracts/#validating-the-emitter)", - "content": "How-to verify messages came from a trusted sender.", - "icon": ":fontawesome-solid-4:" - } -] \ No newline at end of file diff --git a/.snippets/text/build/start-building/supported-networks/connect.md b/.snippets/text/build/start-building/supported-networks/connect.md index bb2f6ba13..42bd24a95 100644 --- a/.snippets/text/build/start-building/supported-networks/connect.md +++ b/.snippets/text/build/start-building/supported-networks/connect.md @@ -4,7 +4,7 @@ ### Connect -
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OsmosisCosmWasm:x::x::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OsmosisCosmWasm:x::x::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
diff --git a/.snippets/text/build/start-building/supported-networks/multigov.md b/.snippets/text/build/start-building/supported-networks/multigov.md index a1207f33a..3ddcd68be 100644 --- a/.snippets/text/build/start-building/supported-networks/multigov.md +++ b/.snippets/text/build/start-building/supported-networks/multigov.md @@ -4,7 +4,7 @@ ### MultiGov -
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::white_check_mark:
SNAXchainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SonicEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::white_check_mark:
SNAXchainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SonicEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
diff --git a/.snippets/text/build/start-building/supported-networks/ntt.md b/.snippets/text/build/start-building/supported-networks/ntt.md index 1df252e00..baa99f35e 100644 --- a/.snippets/text/build/start-building/supported-networks/ntt.md +++ b/.snippets/text/build/start-building/supported-networks/ntt.md @@ -4,7 +4,7 @@ ### NTT -
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
diff --git a/.snippets/text/build/start-building/supported-networks/token-bridge.md b/.snippets/text/build/start-building/supported-networks/token-bridge.md index 96a09e420..5acc005e8 100644 --- a/.snippets/text/build/start-building/supported-networks/token-bridge.md +++ b/.snippets/text/build/start-building/supported-networks/token-bridge.md @@ -4,7 +4,7 @@ ### Token Bridge -
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AlgorandAVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InjectiveCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NEARNEAR VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
Terra 2.0CosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AlgorandAVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InjectiveCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NEARNEAR VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
Terra 2.0CosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
diff --git a/.snippets/text/build/transfers/connect/connect-timeline.json b/.snippets/text/build/transfers/connect/connect-timeline.json deleted file mode 100644 index 140b04685..000000000 --- a/.snippets/text/build/transfers/connect/connect-timeline.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "title": "[Integrate Connect](/docs/build/transfers/connect/overview/#integrate-connect)", - "content": "How-to install via npm package or use hosted CDN.", - "icon": ":fontawesome-solid-1:" - }, - { - "title": "[Configure data](/docs/build/transfers/connect/configuration/configure-data/)", - "content": "How-to specify networks, RPCs, supported tokens, and more.", - "icon": ":fontawesome-solid-2:" - }, - { - "title": "[Customize styling](/docs/build/transfers/connect/configuration/configure-theme/)", - "content": "How-to style your widget with color schemes, fonts, and layout options.", - "icon": ":fontawesome-solid-3:" - } -] diff --git a/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json b/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json deleted file mode 100644 index 50a3584d0..000000000 --- a/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "title": "[Install NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/)", - "content": "The NTT CLI tool provides a comprehensive set of commands for creating, configuring, deploying, and monitoring NTTs.", - "icon": ":fontawesome-solid-1:" - }, - { - "title": "[Configure NTTs](/docs/build/transfers/native-token-transfers/configuration/)", - "content": "Set NTT configuration options to manage Owner and Pauser access control roles and rate-limiting.", - "icon": ":fontawesome-solid-2:" - }, - { - "title": "[Deploy NTTs](/docs/build/transfers/native-token-transfers/deployment-process/)", - "content": "Deploy your NTT to EVM chains and Solana.", - "icon": ":fontawesome-solid-3:" - }, - { - "title": "[Beyond Deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/)", - "content": "Important considerations for managing your NTT integration after deployment. Find links to projects demonstrating NTT integration.", - "icon": ":fontawesome-solid-4:" - } -] \ No newline at end of file diff --git a/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json b/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json deleted file mode 100644 index ed8a8091f..000000000 --- a/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "title": "[Core Contracts](/docs/learn/infrastructure/core-contracts/)", - "content": "Messages are sent from a source contract to the Wormhole Core Contract on the source chain, which publishes them on-chain.", - "icon": ":fontawesome-solid-1:" - }, - { - "title": "[Guardians](/docs/learn/infrastructure/guardians/)", - "content": "Guardians validate these messages before forwarding them to the target chain.", - "icon": ":fontawesome-solid-2:" - }, - { - "title": "[Verifiable Action Approval (VAA)](/docs/learn/infrastructure/vaas/)", - "content": "The validated message is encapsulated in a VAA (Verifiable Action Approval), combining the message with Guardian signatures to create a proof.", - "icon": ":fontawesome-solid-3:" - }, - { - "title": "[Relayers](/docs/learn/infrastructure/relayer/)", - "content": "A relayer relays the VAA to the target chain, which the Wormhole Core Contract then verifies on the target chain.", - "icon": ":fontawesome-solid-4:" - } -] \ No newline at end of file diff --git a/.snippets/text/build/transfers/cctp/DepositForBurn-event.md b/.snippets/text/products/cctp-bridge/guides/cctp-contracts/DepositForBurn-event.md similarity index 100% rename from .snippets/text/build/transfers/cctp/DepositForBurn-event.md rename to .snippets/text/products/cctp-bridge/guides/cctp-contracts/DepositForBurn-event.md diff --git a/.snippets/text/build/transfers/cctp/MessageSent-event.md b/.snippets/text/products/cctp-bridge/guides/cctp-contracts/MessageSent-event.md similarity index 100% rename from .snippets/text/build/transfers/cctp/MessageSent-event.md rename to .snippets/text/products/cctp-bridge/guides/cctp-contracts/MessageSent-event.md diff --git a/.snippets/text/products/connect/overview/connect-timeline.json b/.snippets/text/products/connect/overview/connect-timeline.json new file mode 100644 index 000000000..136464fdb --- /dev/null +++ b/.snippets/text/products/connect/overview/connect-timeline.json @@ -0,0 +1,17 @@ +[ + { + "title": "[Get Started with Connect](/docs/products/connect/get-started/)", + "content": "Integrate Connect into your React or JavaScript application with minimal setup.", + "icon": ":fontawesome-solid-1:" + }, + { + "title": "[Customize Transfer Logic](/docs/products/connect/configuration/data/)", + "content": "Configure supported chains, tokens, and transfer routes to fit your app's needs.", + "icon": ":fontawesome-solid-2:" + }, + { + "title": "[Customize the UI](/docs/products/connect/configuration/theme/)", + "content": "Adapt Connect's interface to match your brand using flexible styling options.", + "icon": ":fontawesome-solid-3:" + } +] diff --git a/.snippets/text/products/multigov/deployment-flow-timeline.json b/.snippets/text/products/multigov/deployment-flow-timeline.json new file mode 100644 index 000000000..d4f0178bb --- /dev/null +++ b/.snippets/text/products/multigov/deployment-flow-timeline.json @@ -0,0 +1,27 @@ +[ + { + "title": "Clone The MultiGov Repository", + "content": "Download the [codebase](https://github.com/wormhole-foundation/multigov) and navigate to the appropriate folder (`evm` or `solana`).", + "icon": ":fontawesome-solid-1:" + }, + { + "title": "Set Up Your Project", + "content": "Install the required toolchain for your target network. For EVM, use Foundry (or similar); for Solana, use Anchor (or similar), Solana CLI, and Rust.", + "icon": ":fontawesome-solid-2:" + }, + { + "title": "Configure Deployment Settings", + "content": "Set environment variables such as RPC URLs, keypairs, and hub chain details in a `.env` file or Anchor config.", + "icon": ":fontawesome-solid-3:" + }, + { + "title": "Deploy MultiGov Contracts or Programs", + "content": "Use the provided scripts to deploy the hub (EVM only) and spoke components (EVM or Solana) to your selected networks.", + "icon": ":fontawesome-solid-4:" + }, + { + "title": "Initialize Governance Configuration", + "content": "Set voting parameters, authorities, and metadata. Use deployment scripts or governance proposals depending on your setup.", + "icon": ":fontawesome-solid-5:" + } +] diff --git a/.snippets/text/products/multigov/multigov-timeline.json b/.snippets/text/products/multigov/multigov-timeline.json new file mode 100644 index 000000000..95fa00240 --- /dev/null +++ b/.snippets/text/products/multigov/multigov-timeline.json @@ -0,0 +1,17 @@ +[ + { + "title": "[Submit an Integration Request with Tally](https://www.tally.xyz/get-started)", + "content": "Apply for MultiGov access by submitting your request to Tally.", + "icon": ":fontawesome-solid-1:" + }, + { + "title": "Deploy MultiGov to the Hub and Spoke Chains of Your Choice", + "content": "**→** [Deploy to EVM chains](/docs/products/multigov/guides/deploy-to-evm/) \n**→** [Deploy to Solana](/docs/products/multigov/guides/deploy-to-solana/)", + "icon": ":fontawesome-solid-2:" + }, + { + "title": "[Create a Treasury Management Proposal](/docs/products/multigov/tutorials/treasury-proposal/)", + "content": "Walk through a real example of creating and executing a cross-chain proposal.", + "icon": ":fontawesome-solid-check:" + } +] diff --git a/.snippets/text/products/native-token-transfers/guides/install-ntt-project.md b/.snippets/text/products/native-token-transfers/guides/install-ntt-project.md new file mode 100644 index 000000000..b048f4504 --- /dev/null +++ b/.snippets/text/products/native-token-transfers/guides/install-ntt-project.md @@ -0,0 +1,38 @@ +Before proceeding, make sure you have the NTT CLI installed and a project initialized. + +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): + +1. Install the NTT CLI: + + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` + + Verify installation: + + ```bash + ntt --version + ``` + +2. Initialize a new NTT project: + + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` + +3. Create the deployment config**: + + === "Mainnet" + + ```bash + ntt init Mainnet + ``` + + === "Testnet" + + ```bash + ntt init Testnet + ``` + + This generates a `deployment.json` file where your deployment settings will be stored. diff --git a/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json b/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json new file mode 100644 index 000000000..6eb6d9a77 --- /dev/null +++ b/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json @@ -0,0 +1,17 @@ +[ + { + "title": "[Get Started with NTT](/docs/products/native-token-transfers/get-started/)", + "content": "Start your journey with Wormhole's NTT by learning to install its CLI, deploy test tokens, and set up it's initial structure for seamless token movement.", + "icon": ":fontawesome-solid-1:" + }, + { + "title": "Deploy NTT", + "content": "Use these resources to deploy NTT across supported chains:

**→** [Deploy to EVM](/docs/products/native-token-transfers/guides/deploy-to-evm/) \n\n**→** [Deploy to EVM Chains via Launchpad](/docs/products/native-token-transfers/guides/evm-launchpad/) \n**→** [Deploy to Solana](/docs/products/native-token-transfers/guides/deploy-to-solana/)", + "icon": ":fontawesome-solid-2:" + }, + { + "title": "Customize NTT", + "content": "Configure crucial operational and security settings for NTT:

**→** [Access control](/docs/products/native-token-transfers/configuration/access-control/) \n**→** [Rate limits](/docs/products/native-token-transfers/configuration/rate-limiting/)", + "icon": ":fontawesome-solid-3:" + } +] \ No newline at end of file diff --git a/.snippets/text/products/queries/queries-timeline.json b/.snippets/text/products/queries/queries-timeline.json new file mode 100644 index 000000000..add29da89 --- /dev/null +++ b/.snippets/text/products/queries/queries-timeline.json @@ -0,0 +1,22 @@ +[ + { + "title": "[Get Started with Queries](/docs/products/queries/get-started/)", + "content": "Install the SDK, request an API key, and run your first verifiable query.", + "icon": ":fontawesome-solid-1:" + }, + { + "title": "[Construct a Query](/docs/products/queries/guides/use-queries/#construct-a-query)", + "content": "Set up the query configuration.", + "icon": ":fontawesome-solid-2:" + }, + { + "title": "[Make a Query Request](/docs/products/queries/guides/use-queries/#make-a-query-request)", + "content": "Send your query to the Query Server using HTTPS.", + "icon": ":fontawesome-solid-3:" + }, + { + "title": "[Submit a Query Response](/docs/products/queries/guides/use-queries/#submit-a-query-response-on-chain)", + "content": "Post the Guardian-signed VAA to your smart contract.", + "icon": ":fontawesome-solid-4:" + } +] diff --git a/.snippets/text/build/reference/chain-ids/chain-ids.md b/.snippets/text/products/reference/chain-ids/chain-ids.md similarity index 100% rename from .snippets/text/build/reference/chain-ids/chain-ids.md rename to .snippets/text/products/reference/chain-ids/chain-ids.md diff --git a/.snippets/text/build/reference/consistency-levels/consistency-levels.md b/.snippets/text/products/reference/consistency-levels/consistency-levels.md similarity index 100% rename from .snippets/text/build/reference/consistency-levels/consistency-levels.md rename to .snippets/text/products/reference/consistency-levels/consistency-levels.md diff --git a/.snippets/text/build/reference/contract-addresses/cctp.md b/.snippets/text/products/reference/contract-addresses/cctp.md similarity index 100% rename from .snippets/text/build/reference/contract-addresses/cctp.md rename to .snippets/text/products/reference/contract-addresses/cctp.md diff --git a/.snippets/text/build/reference/contract-addresses/core-contracts.md b/.snippets/text/products/reference/contract-addresses/core-contracts.md similarity index 100% rename from .snippets/text/build/reference/contract-addresses/core-contracts.md rename to .snippets/text/products/reference/contract-addresses/core-contracts.md diff --git a/.snippets/text/build/reference/contract-addresses/read-only.md b/.snippets/text/products/reference/contract-addresses/read-only.md similarity index 100% rename from .snippets/text/build/reference/contract-addresses/read-only.md rename to .snippets/text/products/reference/contract-addresses/read-only.md diff --git a/.snippets/text/build/reference/contract-addresses/relayer.md b/.snippets/text/products/reference/contract-addresses/relayer.md similarity index 100% rename from .snippets/text/build/reference/contract-addresses/relayer.md rename to .snippets/text/products/reference/contract-addresses/relayer.md diff --git a/.snippets/text/build/reference/contract-addresses/token-bridge.md b/.snippets/text/products/reference/contract-addresses/token-bridge.md similarity index 100% rename from .snippets/text/build/reference/contract-addresses/token-bridge.md rename to .snippets/text/products/reference/contract-addresses/token-bridge.md diff --git a/.snippets/text/products/reference/supported-networks/cctp.md b/.snippets/text/products/reference/supported-networks/cctp.md new file mode 100644 index 000000000..a8cffa344 --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/cctp.md @@ -0,0 +1,10 @@ + + +
+ +### CCTP + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/products/reference/supported-networks/connect.md b/.snippets/text/products/reference/supported-networks/connect.md new file mode 100644 index 000000000..42bd24a95 --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/connect.md @@ -0,0 +1,10 @@ + + +
+ +### Connect + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OsmosisCosmWasm:x::x::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/products/reference/supported-networks/multigov.md b/.snippets/text/products/reference/supported-networks/multigov.md new file mode 100644 index 000000000..3ddcd68be --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/multigov.md @@ -0,0 +1,10 @@ + + +
+ +### MultiGov + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::white_check_mark:
SNAXchainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SonicEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/products/reference/supported-networks/ntt.md b/.snippets/text/products/reference/supported-networks/ntt.md new file mode 100644 index 000000000..baa99f35e --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/ntt.md @@ -0,0 +1,10 @@ + + +
+ +### NTT + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
GnosisEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/products/reference/supported-networks/settlement.md b/.snippets/text/products/reference/supported-networks/settlement.md new file mode 100644 index 000000000..532bd9d38 --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/settlement.md @@ -0,0 +1,10 @@ + + +
+ +### Settlement + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::x::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/products/reference/supported-networks/token-bridge.md b/.snippets/text/products/reference/supported-networks/token-bridge.md new file mode 100644 index 000000000..5acc005e8 --- /dev/null +++ b/.snippets/text/products/reference/supported-networks/token-bridge.md @@ -0,0 +1,10 @@ + + +
+ +### Token Bridge + +
BlockchainEnvironmentMainnetTestnetDevnetQuick Links
EthereumEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SolanaSVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AlgorandAVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AptosMove VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ArbitrumEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
AvalancheEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BaseEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BerachainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BlastEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
BNB Smart ChainEVM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
CeloEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
FantomEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
HyperEVMEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
InjectiveCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
InkEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
KaiaEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
LineaEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MantleEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MezoEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MonadEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
MoonbeamEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NEARNEAR VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
NeonEVM:x::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
OptimismEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
PolygonEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
ScrollEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeiCosmWasm:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SeievmEVM:white_check_mark::white_check_mark::x:
SNAXchainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
SuiSui Move VM:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
Terra 2.0CosmWasm:white_check_mark::white_check_mark::white_check_mark::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
UnichainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
World ChainEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
X LayerEVM:white_check_mark::white_check_mark::x::material-web: Website
:material-file-document: Developer Docs
:octicons-package-16: Block Explorer
+ +
+ diff --git a/.snippets/text/build/start-building/testnet-faucets/testnet-faucets.md b/.snippets/text/products/reference/testnet-faucets/testnet-faucets.md similarity index 98% rename from .snippets/text/build/start-building/testnet-faucets/testnet-faucets.md rename to .snippets/text/products/reference/testnet-faucets/testnet-faucets.md index b83437214..ddee6d0ef 100644 --- a/.snippets/text/build/start-building/testnet-faucets/testnet-faucets.md +++ b/.snippets/text/products/reference/testnet-faucets/testnet-faucets.md @@ -5,7 +5,7 @@ ### EVM -
TestnetEnvironmentTokenFaucet
Ethereum HoleskyEVMETHAlchemy Faucet
Ethereum SepoliaEVMETHAlchemy Faucet
Arbitrum SepoliaEVMETHList of Faucets
AvalancheEVMAVAXOfficial Avalanche Faucet
Base SepoliaEVMETHList of Faucets
BerachainEVMBERAOfficial Berachain Faucet
BlastEVMETHList of Faucets
BNB Smart ChainEVMBNBOfficial BNB Faucet
CeloEVMCELOOfficial Celo Faucet
FantomEVMFTMOfficial Fantom Faucet
GnosisEVMxDAIOfficial Gnosis Faucet
HyperEVMEVMmock USDCOfficial Hyperliquid Faucet
InkEVMETHOfficial Ink Faucet
KaiaEVMKAIAOfficial Kaia Faucet
LineaEVMETHList of Faucets
MantleEVMMNTOfficial Mantle Faucet
MonadEVMMONOfficial Monad Faucet
MoonbeamEVMDEVOfficial Moonbeam Faucet
NeonEVMNEONOfficial Neon Faucet
Optimism SepoliaEVMETHSuperchain Faucet
Polygon AmoyEVMPOLOfficial Polygon Faucet
ScrollEVMETHList of Faucets
UnichainEVMETHQuickNode Faucet
World ChainEVMETHAlchemy Faucet
X LayerEVMOKBX Layer Official Faucet
+
TestnetEnvironmentTokenFaucet
Ethereum HoleskyEVMETHAlchemy Faucet
Ethereum SepoliaEVMETHAlchemy Faucet
Arbitrum SepoliaEVMETHList of Faucets
AvalancheEVMAVAXOfficial Avalanche Faucet
Base SepoliaEVMETHList of Faucets
BerachainEVMBERAOfficial Berachain Faucet
BlastEVMETHList of Faucets
BNB Smart ChainEVMBNBOfficial BNB Faucet
CeloEVMCELOOfficial Celo Faucet
FantomEVMFTMOfficial Fantom Faucet
GnosisEVMxDAIOfficial Gnosis Faucet
HyperEVMEVMmock USDCOfficial Hyperliquid Faucet
InkEVMETHOfficial Ink Faucet
KaiaEVMKAIAOfficial Kaia Faucet
LineaEVMETHList of Faucets
MantleEVMMNTOfficial Mantle Faucet
MonadEVMMONOfficial Monad Faucet
MoonbeamEVMDEVOfficial Moonbeam Faucet
NeonEVMNEONOfficial Neon Faucet
Optimism SepoliaEVMETHSuperchain Faucet
Polygon AmoyEVMPOLOfficial Polygon Faucet
ScrollEVMETHList of Faucets
UnichainEVMETHQuickNode Faucet
World ChainEVMETHAlchemy Faucet
X LayerEVMOKBX Layer Official Faucet
### SVM diff --git a/README.md b/README.md index 2ddaf51c7..0d7973cdb 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This repository includes AI-ready `.txt` files generated from the documentation - `llms-full.txt` – the complete content of all documentation pages in a single file - `llms-*.txt` – category-specific files for products like NTT, Token Bridge, Connect, and others -These files power AI assistants, enable semantic code search, and integrate Wormhole docs into tools like Cursor. For details, visit the [AI Resources](https://wormhole.com/docs/ai-resources/) page. +These files power AI assistants, enable semantic code search, and integrate Wormhole docs into tools like Cursor. For details, visit the [AI Resources](https://wormhole.com/docs/ai-resources/ai-resources/) page. ## Contributing diff --git a/ai-resources/.pages b/ai-resources/.pages new file mode 100644 index 000000000..32fe674c8 --- /dev/null +++ b/ai-resources/.pages @@ -0,0 +1,3 @@ +title: AI Resources +nav: +- 'Download LLM Files': ai-resources.md \ No newline at end of file diff --git a/ai-resources.md b/ai-resources/ai-resources.md similarity index 100% rename from ai-resources.md rename to ai-resources/ai-resources.md diff --git a/build/.pages b/build/.pages deleted file mode 100644 index c13fa51ef..000000000 --- a/build/.pages +++ /dev/null @@ -1,11 +0,0 @@ -title: Build -nav: - - index.md - - start-building - - transfers - - core-messaging - - multigov - - queries - - infrastructure - - toolkit - - reference \ No newline at end of file diff --git a/build/core-messaging/.pages b/build/core-messaging/.pages deleted file mode 100644 index d6ed0b79a..000000000 --- a/build/core-messaging/.pages +++ /dev/null @@ -1,5 +0,0 @@ -title: Core Messaging -nav: - - index.md - - 'Wormhole Relayer': 'wormhole-relayers.md' - - 'Core Contracts': 'core-contracts.md' diff --git a/build/core-messaging/index.md b/build/core-messaging/index.md deleted file mode 100644 index 254753fdb..000000000 --- a/build/core-messaging/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Core Messaging Layer Contracts -description: Learn to use Wormhole’s foundational messaging contracts to build multichain apps with direct control over publishing, verifying, relaying, and more. ---- - -# Core Messaging - -Wormhole-deployed relayers and Core Contracts are essential for sending and receiving multichain messages. Learning to work directly with these building blocks offers a deeper understanding of Wormhole and increased control and customization options. - -Follow the links below for how-to guides about using Core Contracts and Wormhole-deployed relayers to send, receive, validate, and track multichain messages. - -## Simplified Message Flow - - -Wormhole-deployed relayer support is limited to EVM environments. For a complete list of supported EVM environment blockchains, see the [Supported Networks](/docs/build/start-building/supported-networks/){target=\_blank} page. - -[timeline(wormhole-docs/.snippets/text/build/core-messaging/core-messaging-timeline.json)] - -## Next Steps - -
- -- :octicons-tools-16:{ .lg .middle} **Get Started with Core Contracts** - - --- - - Follow this series of how-to guides about interacting with Core Contracts to send, receive, and validate messages. - - [:custom-arrow: Get started](/docs/build/core-messaging/core-contracts/#prerequisites) - -- :octicons-tools-16:{ .lg .middle } **Get Started with Relayers** - - --- - - Follow this series of how-to guides about using Wormhole-deployed relayers to send, receive, and track the progress of messages. - - [:custom-arrow: Get started](/docs/build/core-messaging/wormhole-relayers/#get-started-with-the-wormhole-relayer) - -
diff --git a/build/index.md b/build/index.md deleted file mode 100644 index 726bb432b..000000000 --- a/build/index.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Build with Wormhole -description: Learn how to start building multichain solutions on Wormhole, with tips to get started, an overview of the toolkit, and an introduction to the protocols. -template: root-index-page.html ---- - -# Build - -## Quick Start: Step-by-Step Tutorials - -If you learn best by building, start here to build with the Wormhole TypeScript SDK: - -- [**Transfer Tokens via the Token Bridge**](/docs/tutorials/typescript-sdk/tokens-via-token-bridge/){target=\_blank} - use the [Wormhole SDK's](/docs/build/toolkit/typescript-sdk/){target=\_blank} Token Bridge method to move wrapped assets across networks - -- [**Transfer USDC via CCTP and Wormhole SDK**](/docs/tutorials/typescript-sdk/usdc-via-cctp/){target=\_blank} - combine the [Wormhole SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} and Circle's Cross-Chain Transfer Protocol (CCTP) to bridge native USDC across networks - -Alternatively, start here to work with Wormhole contracts directly: - -- [**Create Multichain Messaging Contracts**](/docs/tutorials/solidity-sdk/cross-chain-contracts/) - create mulitchain contracts using Wormhole's Solidity SDK. You will deploy smart contracts and send messages across chains - -- [**Create Multichain Token Transfer Contracts**](/docs/tutorials/solidity-sdk/cross-chain-token-contracts/) - create multichain token transfers using Wormhole's Solidity SDK. You will build and deploy smart contracts to send tokens from one blockchain to another - -## Builder Essentials - -Access essential information and tools quickly: - -
- -- :octicons-tools-16:{ .lg .middle } **Supported Networks** - - --- - - Supported blockchains by environment - main or testnet availability and quick links to the website, documentation, and block explorer for each network. - - [:custom-arrow: Supported Networks](/docs/build/start-building/supported-networks/) - -- :octicons-tools-16:{ .lg .middle } **Testnet Faucets** - - --- - - Links to testnet token faucets for supported networks. - - [:custom-arrow: Get Testnet Tokens](/docs/build/start-building/testnet-faucets/) - -- :octicons-tools-16:{ .lg .middle } **Wormhole TypeScript SDK** - - --- - - Your guide to Wormhole SDK installation and usage, concepts overview, and code samples. - - [:custom-arrow: Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/wormhole-sdk/) - -- :octicons-tools-16:{ .lg .middle } **Reference** - - --- - - Wormhole chain ID, contract address, address formatting and conversion, and consistency information. - - [:custom-arrow: Reference](/docs/build/reference/) - -
- -## Integrate Transfer Products - -
- -- :octicons-tools-16:{ .lg .middle } **Multichain Transfers** - - --- - - - **Connect UI widget** - easy-to-use UI for multichain asset transfers via Wormhole in a web application - - **Native Token Transfers (NTT)** - native asset transfer, without the need for wrapped assets - - **Token Bridge** - transfer wrapped assets with optional message payloads - - **Settlement** - intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more - - [:custom-arrow: Build Multichain Transfers](/docs/build/transfers/) - -
- -## Access Real-Time Data - -
- -- :octicons-tools-16:{ .lg .middle } **Real-Time Data** - - --- - - - **Wormhole Queries** - on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy - - **Supported query types** - includes query equivalents for `eth_call` (with options for timestamp and finality), `sol_account`, and `sol_pda` - - **Use familiar endpoints** - make calls against the RPC provider endpoints you already know and use - - [:custom-arrow: Build with Queries](/docs/build/queries/) - -
- -## Multichain Governance - -
- -- :octicons-tools-16:{ .lg .middle } **MultiGov** - - --- - - - **Wormhole's MultiGov** - a multichain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks - - **Hub-and-spoke model** - spoke chain contracts handle local voting and proposals with results sent to the hub for vote aggregation and tallying, proposal management, and coordinating governance across connected chains - - **Wormhole security** - moving vote weight checkpoints, timelocks, and Wormhole verification keep governance activity secure - - [:custom-arrow: Build with MultiGov](/docs/build/multigov/) - -
- diff --git a/build/infrastructure/.pages b/build/infrastructure/.pages deleted file mode 100644 index a81fc0035..000000000 --- a/build/infrastructure/.pages +++ /dev/null @@ -1,5 +0,0 @@ -title: Infrastructure -nav: - - index.md - - relayers - - spy diff --git a/build/infrastructure/index.md b/build/infrastructure/index.md deleted file mode 100644 index 8dcc26453..000000000 --- a/build/infrastructure/index.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Run Infrastructure Services -description: Follow the guides in this section to learn how to run off-chain infrastructure services, such as running a spy or a customized relayer. -# template: root-index-page.html ---- - -# Infrastructure - -## Get Started - -Follow the guides in this section to learn how to run off-chain infrastructure services, such as running a spy or a customized relayer. - -
- -- :octicons-terminal-16:{ .lg .middle } **Relayers** - - --- - - Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. - - [:custom-arrow: Run a relayer](/docs/infrastructure/relayers/run-relayer/) - -
- -
- -- :octicons-terminal-16:{ .lg .middle } **Spy** - - --- - - Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. - - [:custom-arrow: Run a Spy](/docs/infrastructure/spy/run-spy/) - -
diff --git a/build/infrastructure/relayers/.pages b/build/infrastructure/relayers/.pages deleted file mode 100644 index f96d27c04..000000000 --- a/build/infrastructure/relayers/.pages +++ /dev/null @@ -1,4 +0,0 @@ -title: Relayers -nav: - - index.md - - 'Run a Custom Relayer': 'run-relayer.md' diff --git a/build/infrastructure/relayers/index.md b/build/infrastructure/relayers/index.md deleted file mode 100644 index 6239aab02..000000000 --- a/build/infrastructure/relayers/index.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Relayers -description: Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. -categories: Relayers ---- - -# Relayers - -## Get Started - -
- -- :octicons-terminal-16:{ .lg .middle } **Run a Custom Relayer** - - --- - - This section guides you through developing your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. - -
- - Benefits of running your own relayer: - - - You can add logic to customize the delivery of messages - - You can perform off-chain computations resulting in optimized gas costs - -
- - Requirements for running your own relayer: - - - You are responsible for developing and hosting your relayer - - You are responsible for paying target chain fees - - You are responsible for the liveness of your relayer - -
- - [:custom-arrow: Get started now](/docs/infrastructure/relayers/run-relayer/) - -
- -## Additional Resources - -
- -- :octicons-question-16:{ .lg .middle } **What is a Relayer?** - - --- - - Learn about what a relayer is, what role it plays in the delivery of cross-chain messages, and the different types of relayers in the Wormhole ecosystem. - - [:custom-arrow: Learn more about relayers](/docs/learn/infrastructure/relayer/) - -- :octicons-gear-16:{ .lg .middle } **Simplify the Development Process** - - --- - - Use the Wormhole Relayer Engine package as a foundational toolkit to develop your own customized off-chain relaying service, enabling tailored message handling. - - [:custom-arrow: Check out the Relayer Engine source code](https://github.com/wormhole-foundation/relayer-engine){target=\_blank} - -
diff --git a/build/infrastructure/spy/.pages b/build/infrastructure/spy/.pages deleted file mode 100644 index 2862060b4..000000000 --- a/build/infrastructure/spy/.pages +++ /dev/null @@ -1,4 +0,0 @@ -title: Spy -nav: - - index.md - - 'Run a Spy': 'run-spy.md' diff --git a/build/infrastructure/spy/index.md b/build/infrastructure/spy/index.md deleted file mode 100644 index 1385172f4..000000000 --- a/build/infrastructure/spy/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Spy -description: Discover everything you need to about the Wormhole Spy, a daemon that watches the Guardian Network and subscribe to signed messages. ---- - -# Spy - -## Get Started - -
- -- :octicons-terminal-16:{ .lg .middle } **Run a Spy** - - --- - - The content in this section shows you how you can run your own infrastructure and spin up a Spy daemon locally to subscribe to a stream of messages, also known as Verifiable Action Approvals (VAAs). - - [:custom-arrow: Get started now](/docs/infrastructure/spy/run-spy/) - -
- -## Additional Resources - -
- -- :octicons-question-16:{ .lg .middle } **What is a Spy?** - - --- - - Learn about what a Spy is and what role it plays in the delivery of cross-chain messages. - - [:custom-arrow: Learn more about Spies](/docs/learn/infrastructure/spy/) - -- :octicons-code-16:{ .lg .middle } **Interact with a Spy** - - --- - - Use the Wormhole Spy SDK to subscribe to the stream of signed messages. - - [:custom-arrow: Use the Wormhole Spy SDK](https://github.com/wormhole-foundation/wormhole/blob/main/spydk/js/README.md){target=\_blank} - -- :octicons-bookmark-16:{ .lg .middle } **Alternative Implementations** - - --- - - Check out Beacon, an alternative highly available version of the Wormhole Spy. - - [:custom-arrow: Use Pyth Beacon](https://github.com/pyth-network/beacon){target=\_blank} - -
diff --git a/build/multigov/.pages b/build/multigov/.pages deleted file mode 100644 index 7583c1b18..000000000 --- a/build/multigov/.pages +++ /dev/null @@ -1,8 +0,0 @@ -title: Multichain Governance (MultiGov) -nav: - - index.md - - 'Deploy to EVM': 'deploy-to-evm.md' - - 'Deploy to Solana': 'deploy-to-solana.md' - - 'Upgrade Contracts on EVM Chains': 'upgrade-evm.md' - - 'Upgrade Contracts on Solana': 'upgrade-solana.md' - - 'Technical FAQs': 'faq.md' diff --git a/build/multigov/index.md b/build/multigov/index.md deleted file mode 100644 index b3e63e33b..000000000 --- a/build/multigov/index.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Getting Started with MultiGov -description: Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. -categories: MultiGov ---- - -# MultiGov - -## Begin the MultiGov Integration Process - -Take the following steps to get started with a MultiGov integration: - -1. Evaluate if [MultiGov](/docs/learn/governance/) meets your cross-chain governance needs -2. Fill out the intake form on the [Tally website](https://www.tally.xyz/get-started){target=\_blank} -3. The Tally team will review your application and contact you to discuss implementation details -4. Work with the Tally team to customize and deploy MultiGov for your specific use case - -## Start Building - -
- -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** - - --- - - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. - - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** - - --- - - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. - - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) - -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on EVM Chains** - - --- - - Learn the process and key considerations for upgrading MultiGov contracts, ensuring system integrity and careful planning across cross-chain components. - - [:custom-arrow: Discover how to upgrade MultiGov on EVM Chains](/docs/build/multigov/upgrade-evm/) - -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on Solana** - - --- - - Learn how to upgrade the MultiGov Staking Program on Solana, including updating the program binary, IDL, and more. - - [:custom-arrow: Discover how to upgrade MultiGov on Solana](/docs/build/multigov/upgrade-solana/) - -- :octicons-question-16:{ .lg .middle } **Technical FAQs** - - --- - - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. - - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) - -
- -## Additional Resources - -
- -- :octicons-book-16:{ .lg .middle } **What is MultiGov?** - - --- - - Need to familiarize yourself with MultiGov? Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. - - [:custom-arrow: Learn the basics](/docs/learn/governance/) - -- :octicons-checklist-16:{ .lg .middle } **Tutorials** - - --- - - Access step-by-step tutorials for executing cross-chain governance actions, including treasury management proposals with MultiGov. - - [:custom-arrow: Learn by building](/docs/tutorials/multigov/) - -
diff --git a/build/queries/.pages b/build/queries/.pages deleted file mode 100644 index e151b6700..000000000 --- a/build/queries/.pages +++ /dev/null @@ -1,6 +0,0 @@ -title: Real-time Data (Queries) -nav: - - index.md - - 'Overview': overview.md - - 'Use Queries': use-queries.md - - 'FAQs': faqs.md diff --git a/build/queries/index.md b/build/queries/index.md deleted file mode 100644 index 845df06b6..000000000 --- a/build/queries/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Wormhole Queries -description: Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. -categories: Queries ---- - -# Queries - -## Get Started - -Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. - -
- -- :octicons-book-16:{ .lg .middle } **Overview** - - --- - - Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST API endpoint, enabling secure cross-chain interactions and verifications. - - [:custom-arrow: Learn about Queries](/docs/build/queries/overview/) - -- :octicons-code-16:{ .lg .middle } **Use Queries** - - --- - - Explore a simple demo of interacting with Wormhole Queries using an `eth_call` request to query the supply of wETH on Ethereum using a Wormhole query. - - [:custom-arrow: Get hands-on](/docs/build/queries/use-queries/) - -- :octicons-book-16:{ .lg .middle } **Query FAQs** - - --- - - Explore frequently asked questions about Wormhole Queries. - - [:custom-arrow: Check out the FAQs](/docs/build/queries/faqs/) - -
diff --git a/build/queries/overview.md b/build/queries/overview.md deleted file mode 100644 index 40c19d82d..000000000 --- a/build/queries/overview.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Queries Overview -description: Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST endpoint, enabling secure cross-chain interactions and verifications. -categories: Queries ---- - -# Queries Overview {: #queries-overview } - -Wormhole Guardians, who run full nodes for various connected chains, facilitate a new cross-chain query service that allows for on-demand attested responses to queries, bypassing the inefficiencies of traditional transaction-based data retrieval. This method is faster and cost-effective, eliminating the need for gas payments and transaction finality wait times. - -!!! note - Queries are currently in closed beta, though you can start developing today. Check out [Use Queries](/docs/build/queries/use-queries/){target=\_blank} and reach out to [Join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. - -Wormhole Queries offers on-demand access to Guardian-attested on-chain data. The current implementation provides integrators with a simple REST endpoint to initiate an off-chain request via a proxy. The proxy then forwards the request to the Guardians and gathers a quorum of responses. The result returns the encoded response, including the request details and the Guardian signatures. The request validation performed by the query module includes a three step process that involves verifying the signature to ensure it has the correct prefix, confirming that the signer is authorized to execute query requests, and validating the legitimacy of all per-chain requests contained in the query. You can read more about Queries in the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank}. - -## The Flow of a Query {: #the-flow-of-a-query} - -The general overview of a query's flow is as follows: an off-chain process sends HTTPS query requests to a Query Proxy, which validates and forwards them to the Guardians; these Guardians independently validate, sign, and return the response, with the entire process typically taking less than a second. - -![The architecture flow of a query](/docs/images/build/queries/overview/overview-1.webp) - -The step-by-step flow of a query is as follows: - -1. An off-chain process initiates a query request via HTTPS to the query proxy (or Query Server) -2. The query proxy validates the request and forwards it to the Guardians via a gossip network -3. The Guardians independently validate the request, make the requisite RPC calls, verify the results, sign, and gossip a response back to the Query Proxy -4. The Query Proxy aggregates the results and returns a response when it reaches a quorum of two-thirds or more of the current Guardian set - the exact quorum requirements as the core bridge -5. The off-chain process can then submit these requests to an on-chain contract which should verify the signatures and validate the request before processing the result - -In this flow, the Query Proxy is a permissioned but trustless part of the protocol. In most cases, this entire process takes less than one second. If a request is invalid or cannot be processed by the Guardians, they will retry for up to one minute before timing out. Requests can be batched to have the Guardians make multiple calls to multiple networks. This can further reduce overhead for processing query responses on-chain. Up to 255 queries can be batched together, with certain types allowing for batching themselves. - -## Supported Query Types {: #supported-query-types} - -There are currently five supported types of queries. See [the white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank} for more details on each. - -### eth_call {: #eth-call} - -This query type is effectively an equivalent of [eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a block specified by number or hash. - -Calls are batched to allow specifying multiple calls (even to multiple contracts) against the same block. These calls are included in a single batch RPC call, simplifying on-chain verification. Up to 255 calls may be batched in an single `eth_call` query. - -The result contains the specified block number, hash, timestamp, and the call result. - -### eth_call By Timestamp {: #eth-call-by-timestamp} - -This query type is similar to `eth_call` but targets a timestamp instead of a specific `block_id`. This can be useful when forming requests based on uncorrelated data, such as requiring data from another chain based on the block timestamp of a given chain. - -The result also contains the target and block details with the following enforced conditions: `target_block.timestamp <= target_time < following_block.timestamp` and `following_block_num - 1 == target_block_num`. - -### eth_call With Finality {: #eth-call-with-finality} - -This query type is similar to `eth_call` but ensures that the specified block has reached the specified finality before returning the query results. The finality may be `finalized` or `safe.` Note that if a chain doesn't natively support the `safe` tag, this will be equivalent to `finalized.` - -### sol_account {: #sol_account} - -This query is used to read data for one or more accounts on Solana, akin to [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank}. - -### sol_pda {: #sol_pda} - -This query is used to read data for one or more [Program Derived Addresses(PDA)](https://www.anchor-lang.com/docs/pdas){target=\_blank} on Solana, akin to calling [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} on the result of `PublicKey.findProgramAddressSync(seeds, programId).` This query is helpful for times when you want to more generally read accounts owned by a program and verify the derivation on another chain, like how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. - -## Supported Chains {: #supported-chains} - -The following table provides expected support based on testing. However, the success of any given query is based on the success of the underlying call on each Guardian’s RPC node. - -For example, many chains have implementations forked from [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which keeps 128 blocks of state in memory by default (without running in archive mode). While this is good for about 25 minutes of history on Ethereum Mainnet, it is only about three minutes on Optimism. While Guardian nodes can be expected to have access to recent state, there are currently no guarantees of how far back in history they have access to. - -### Mainnet {: #mainnet} - -| Chain | Wormhole Chain ID | eth_call | By Timestamp | With Finality | Expected History | -|:-------------:|:-----------------:|:--------:|:------------------:|:-------------:|:----------------:| -| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | -| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | -| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | -| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | -| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | -| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | -| Karura | 11 | ✅ | ✅ | ✅ | archive | -| Acala | 12 | ✅ | ✅ | ✅ | archive | -| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | -| Celo | 14 | ✅ | ℹ️ hints required\* | ✅ | 128 blocks | -| Moonbeam | 16 | ✅ | ℹ️ hints required\* | ✅ | 256 blocks | -| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | -| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | -| Base | 30 | ✅ | ✅ | ✅ | archive | - -\*`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. - -## Next Steps {: #next-steps} - -Remember that Wormhole Queries are currently in beta. You can [register to join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to fully experiment with Wormhole Queries. - -Be sure to check out the [FAQs](/docs/build/queries/faqs/){target=\_blank} and the [Use Queries guide](/docs/build/queries/use-queries/){target=\_blank}. - -You can also check out the following examples of applications that make use of Wormhole Queries: - -- [Basic demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} -- [Solana Stake Pool](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} -- [Solana Program Derived Address (PDA) / Token Account Balance](https://github.com/wormholelabs-xyz/example-queries-solana-pda){target=\_blank} -- [Solana Queries Verification](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} \ No newline at end of file diff --git a/build/reference/.pages b/build/reference/.pages deleted file mode 100644 index c4775bfd5..000000000 --- a/build/reference/.pages +++ /dev/null @@ -1,7 +0,0 @@ -title: Reference -nav: - - index.md - - 'Chain IDs' : 'chain-ids.md' - - 'Contract Addresses' : 'contract-addresses.md' - - 'Wormhole Finality': 'consistency-levels.md' - - 'Wormhole Formatted Addresses': 'wormhole-formatted-addresses.md' diff --git a/build/reference/contract-addresses.md b/build/reference/contract-addresses.md deleted file mode 100644 index 2c0df7ec1..000000000 --- a/build/reference/contract-addresses.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Contract Addresses -description: This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. -categories: Reference ---- - -# Contract Addresses - -## Core Contracts - ---8<-- 'text/build/reference/contract-addresses/core-contracts.md' - -## Token Bridge - ---8<-- 'text/build/reference/contract-addresses/token-bridge.md' - -## Wormhole Relayer - ---8<-- 'text/build/reference/contract-addresses/relayer.md' - -## CCTP - ---8<-- 'text/build/reference/contract-addresses/cctp.md' - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - ---8<-- 'text/build/reference/contract-addresses/read-only.md' - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. - diff --git a/build/reference/index.md b/build/reference/index.md deleted file mode 100644 index 74263d299..000000000 --- a/build/reference/index.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- - -# Reference - -## Get Started - -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. - -
- -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** - - --- - - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. - - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) - -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** - - --- - - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. - - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) - -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** - - --- - - Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. - - This includes the following protocol contracts: - - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP - - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) - -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** - - --- - - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. - - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) - -
diff --git a/build/start-building/.pages b/build/start-building/.pages deleted file mode 100644 index 970b3c6a5..000000000 --- a/build/start-building/.pages +++ /dev/null @@ -1,8 +0,0 @@ -title: Start Building -nav: - - index.md - - 'Product Comparison': 'products.md' - - 'Use Cases': 'use-cases.md' - - 'Supported Networks': 'supported-networks.md' - - 'Testnet Faucets': 'testnet-faucets.md' - - 'Explorer': 'https://wormholescan.io/' diff --git a/build/start-building/index.md b/build/start-building/index.md deleted file mode 100644 index 0e0638afb..000000000 --- a/build/start-building/index.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Start Building -description: This section has all you need to start developing with Wormhole, including a guide to supported networks, tool sets, and code examples. ---- - -# Start Building - -Wormhole's role as a Generic Message Passing (GMP) protocol means it facilitates interoperability across multiple areas of project development. The following sections will help you locate the tools most relevant to your development needs whether you are focused on building frontend user interfaces or smart contracts and protocols. This section also links to developer resources like references and code examples which are helpful for all builders looking to integrate with Wormhole. - -## Get Hands-On - -
- -- :octicons-repo-16:{ .lg .middle } **Tutorials** - - --- - - Follow in-depth, step-by-step tutorials to learn how to build cross-chain contracts, integrate Wormhole's SDK, and more. - - [:custom-arrow: Explore tutorials](/docs/tutorials/) - -
- -## Essential Resources for Development - -
- -- :octicons-broadcast-16:{ .lg .middle } **Supported Networks** - - --- - - Explore the blockchains supported by Wormhole for cross-chain communication and asset transfers. Understand which networks are available for both Testnet and Mainnet environments. - - [:custom-arrow: Discover supported networks](/docs/build/start-building/supported-networks/) - -- :octicons-goal-16:{ .lg .middle } **Testnet Faucets** - - --- - - Get Testnet tokens to start experimenting with cross-chain transfers and contract deployment. - - [:custom-arrow: Find Testnet faucets](/docs/build/start-building/testnet-faucets/) - -- :octicons-list-unordered-16:{ .lg .middle } **Reference** - - --- - - Access the essential Wormhole chain IDs and smart contract addresses for messaging protocols, token bridges, and other key components. - - [:custom-arrow: Explore Reference](/docs/build/reference/){target=\_blank} - -
diff --git a/build/start-building/use-cases.md b/build/start-building/use-cases.md deleted file mode 100644 index fd0b89698..000000000 --- a/build/start-building/use-cases.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- - -# Wormhole Use Cases - -
-
- -## Cross-Chain Swaps and Liquidity Aggregation - -Enable seamless swaps between chains with real-time liquidity routing. - -
-
- -🛠 **Wormhole products used:** - -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution - -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} - -
-
- - -
-
- -## Borrowing and Lending Across Chains - -Let users borrow assets on one chain using collateral from another. - -
-
- -🛠 **Wormhole products used:** - -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time - -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} - -
-
- - -
-
- -## Real-Time Price Feeds and Trading Strategies - -Fetch price feeds across multiple chains for DeFi applications. - -
-
- -🛠 **Wormhole products used:** - -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades - -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} - -
-
- - -
-
- -## Asset Movement Between Bitcoin and Other Chains - -Enable direct BTC transfers without wrapped assets. - -
-
- -🛠 **Wormhole products used:** - -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains - -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} - -
-
- -
-
- -## Decentralized Social Platforms - -Enable seamless communication and asset transfer across decentralized social networks. - -
-
- -🛠 **Wormhole products used:** - -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards - -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} - -
-
- - -
-
- -## Memecoin Launchpads - -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. - -
-
- -🛠 **Wormhole products used:** - -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes - -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems - -
-
- - -
-
- -## Cross-Chain Perpetuals - -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. - -
-
- -🛠 **Wormhole products used:** - -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences - -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives - -
-
- - -
-
- -## Gas Abstraction - -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. - -
-
- -🛠 **Wormhole products used:** - -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments - -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements - -
-
- - -
-
- -## Bridging Intent Library - -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. - -
-
- -🛠 **Wormhole products used:** - -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents - -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries - -
-
- - -
-
- -## Multichain Prediction Markets - -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. - -
-
- -🛠 **Wormhole products used:** - -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions - -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming - -
-
- - -
-
- -## Cross-Chain Payment Widgets - -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. - -
-
- -🛠 **Wormhole products used:** - -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers - -🔗 **Used in:** E-commerce, Web3 payments, and subscription models - -
-
- - -
-
- -## Oracle Networks - -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. - -
-
- -🛠 **Wormhole products used:** - -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks - -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} - -
-
- - -
-
- -## Cross-Chain Staking - -Enable users to stake assets on one chain while earning rewards or securing networks on another. - -
-
- -🛠 **Wormhole products used:** - -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks - -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} - -
-
\ No newline at end of file diff --git a/build/toolkit/.pages b/build/toolkit/.pages deleted file mode 100644 index 38f4108e9..000000000 --- a/build/toolkit/.pages +++ /dev/null @@ -1,8 +0,0 @@ -title: Toolkit -nav: - - index.md - - typescript-sdk - - 'Solidity SDK': 'solidity-sdk.md' - - 'Wormholescan API': 'https://wormholescan.io/#/developers/api-doc' -# - 'Development Environment': 'dev-env.md' -# - 'FAQs': 'faqs.md' diff --git a/build/toolkit/index.md b/build/toolkit/index.md deleted file mode 100644 index b5619a221..000000000 --- a/build/toolkit/index.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Wormhole Tooling -description: This page lists key dev tools, including the WormholeScan Explorer, Wormhole CLI, Wormhole SDKs, and APIs for querying network data. -categories: Solidity-SDK ---- - -# Wormhole Tooling - -Regardless of which network development environment you are using, there are a few Wormhole-specific tools you should know about. - -## Get Started - -
- -- :octicons-telescope-16:{ .lg .middle } **Wormholescan** - - --- - - Wormholescan is an explorer for looking at individual transfer statuses on Mainnet and Testnet. - - [:custom-arrow: Review transactions on Wormholescan](https://wormholescan.io){target=\_blank} - -- :octicons-plug-16:{ .lg .middle } **Wormholescan API** - - --- - - Leverage the Wormholescan API to programmatically access Wormhole network data, including transaction details and VAAs. - - [:custom-arrow: Explore the Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} - -- :octicons-code-square-16:{ .lg .middle } **Wormhole CLI Tool** - - --- - - The Wormhole CLI is a Swiss-Army knife utility command line tool. It is excellent for creating one-off VAAs, parsing VAAs, reading Wormhole contract configurations, and more. - - [:custom-arrow: Get started with the CLI](/docs/build/toolkit/cli/) - -- :octicons-code-square-16:{ .lg .middle } **Wormhole SDK** - - --- - - Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC transfers. - - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/typescript-sdk/) - -- :octicons-code-square-16:{ .lg .middle } **Solidity SDK** - - --- - - Learn about Wormhole's Solidity SDK, including key components, interfaces, and tools for developing cross-chain decentralized applications on EVM-compatible blockchains. - - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/solidity-sdk/) - -- :octicons-beaker-16:{ .lg .middle } **Tilt** - - --- - - Learn about Tilt, a Wormhole developer environment with a local Kubernetes set up for cross-chain testing with Guardian nodes and relayers for seamless development. - - [:custom-arrow: Get started with Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} - - - -
- -## Additional Resources - -
- -- :octicons-code-square-16:{ .lg .middle } **Wormhole Spy SDK** - - --- - - The Wormhole Spy SDK allows you to listen to all the Guardian Network activity. - - [:custom-arrow: Check out the Spy SDK repository](https://github.com/wormhole-foundation/wormhole/tree/main/spydk/js){target=\_blank} - -- :octicons-pencil-16:{ .lg .middle } **VAA Parser** - - --- - - The VAA Parser is a resource for parsing out details of an encoded VAA. - - [:custom-arrow: Try the VAA Parser](https://wormholescan.io/#/developers/vaa-parser){target=\_blank} - -
diff --git a/build/toolkit/typescript-sdk/index.md b/build/toolkit/typescript-sdk/index.md deleted file mode 100644 index 4c97b8137..000000000 --- a/build/toolkit/typescript-sdk/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Wormhole SDK -description: The Wormhole SDK provides tools for cross-chain communication, token bridges, and more, enabling developers to integrate with multiple blockchain environments. -categories: Typescript-SDK ---- - -# Wormhole SDK - -## Get Started - -The Wormhole SDK provides developers with essential tools for cross-chain communication, token bridges, and more. This SDK enables seamless interaction between different blockchain environments with a focus on performance and usability. - -
- -- :octicons-book-16:{ .lg .middle } **Wormhole SDK** - - --- - - Learn about the core functionalities of the Wormhole SDK, including how to use its features for building cross-chain applications. - - [:custom-arrow: Explore the SDK](/docs/build/toolkit/typescript-sdk/wormhole-sdk/) - -- :octicons-code-16:{ .lg .middle } **Layouts** - - --- - - Discover how to define, serialize, and deserialize data structures using the Wormhole SDK's layout system, ensuring efficient cross-chain communication. - - [:custom-arrow: Learn about layouts](/docs/build/toolkit/typescript-sdk/sdk-layout/) - -
diff --git a/build/toolkit/typescript-sdk/wormhole-sdk.md b/build/toolkit/typescript-sdk/wormhole-sdk.md deleted file mode 100644 index d5f4ed847..000000000 --- a/build/toolkit/typescript-sdk/wormhole-sdk.md +++ /dev/null @@ -1,398 +0,0 @@ ---- -title: Wormhole TS SDK -description: Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC. -categories: Typescript-SDK ---- - -# Wormhole TypeScript SDK - -## Introduction - -The Wormhole TypeScript SDK is useful for interacting with the chains Wormhole supports and the [protocols](#protocols) built on top of Wormhole. This package bundles together functions, definitions, and constants that streamline the process of connecting chains and completing transfers using Wormhole. The SDK also offers targeted sub-packages for Wormhole-connected platforms, which allow you to add multichain support without creating outsized dependencies. - -This section covers all you need to know about the functionality and ease of development offered through the Wormhole TypeScript SDK. Take a tour of the package to discover how it helps make integration easier. Learn more about how the SDK abstracts away complexities around concepts like platforms, contexts, and signers. Finally, you'll find guidance on usage, along with code examples, to show you how to use the tools of the SDK. - - -
- -- :octicons-download-16:{ .lg .middle } **Installation** - - --- - - Find installation instructions for both the meta package and installing specific, individual packages - - [:custom-arrow: Install the SDK](#installation) - -- :octicons-book-16:{ .lg .middle } **Concepts** - - --- - - Understand key concepts and how the SDK abstracts them away. Learn more about platforms, chain context, addresses, and signers - - [:custom-arrow: Explore concepts](#concepts) - -- :octicons-file-code-16:{ .lg .middle } **Usage** - - --- - - Guidance on using the SDK to add seamless interchain messaging to your application, including code examples - - [:custom-arrow: Use the SDK](#usage) - -- :octicons-code-square-16:{ .lg .middle } **TSdoc for SDK** - - --- - - Review the TSdoc for the Wormhole TypeScript SDK for a detailed look at availabel methods, classes, interfaces, and definitions - - [:custom-arrow: View the TSdoc on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank} - -
- -!!! warning - This package is a work in progress. The interface may change, and there are likely bugs. Please [report](https://github.com/wormhole-foundation/connect-sdk/issues){target=\_blank} any issues you find. - -## Installation - -### Basic - -To install the meta package using npm, run the following command in the root directory of your project: - -```bash -npm install @wormhole-foundation/sdk -``` - -This package combines all the individual packages to make setup easier while allowing for tree shaking. - -### Advanced - -Alternatively, you can install a specific set of published packages individually: - -??? interface "`sdk-base` - exposes constants" - - ```sh - npm install @wormhole-foundation/sdk-base - ``` - -??? interface "`sdk-definitions` - exposes contract interfaces, basic types, and VAA payload definitions" - - ```sh - npm install @wormhole-foundation/sdk-definitions - ``` - -??? interface "`sdk-evm` - exposes EVM-specific utilities" - - ```sh - npm install @wormhole-foundation/sdk-evm - ``` - -??? interface "`sdk-evm-tokenbridge` - exposes the EVM Token Bridge protocol client" - - ```sh - npm install @wormhole-foundation/sdk-evm-tokenbridge - ``` - -## Usage - -Getting your integration started is simple. First, import Wormhole: - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts::1' -``` - -Then, import each of the ecosystem [platforms](#platforms) that you wish to support: - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts:4:9' -``` - - -To make the [platform](#platforms) modules available for use, pass them to the Wormhole constructor: - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts:13:20' -``` - -With a configured Wormhole object, you can do things like parse addresses for the provided platforms, get a [`ChainContext`](#chain-context) object, or fetch VAAs. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts:22:22' -``` - -You can retrieve a VAA as follows. In this example, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will vary by network. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts:54:61' -``` - -??? code "View the complete script" - ```ts - --8<-- 'code/build/toolkit/typescript-sdk/get-vaa.ts' - ``` - -Optionally, you can override the default configuration with a partial `WormholeConfig` object to specify particular fields, such as a different RPC endpoint. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/config-override.ts' -``` - -??? code "View the complete script" - ```ts - --8<-- 'code/build/toolkit/typescript-sdk/config.ts' - ``` - -## Concepts - -Understanding several higher-level Wormhole concepts and how the SDK abstracts them away will help you use the tools most effectively. The following sections will introduce and discuss the concepts of platforms, chain contexts, addresses, signers, and protocols, how they are used in the Wormhole context, and how the SDK helps ease development in each conceptual area. - -### Platforms - -While every chain has unique attributes, chains from the same platform typically have standard functionalities they share. The SDK includes `Platform` modules, which create a standardized interface for interacting with the chains of a supported platform. The contents of a module vary by platform but can include: - -- Protocols, such as [Wormhole core](#wormhole-core), preconfigured to suit the selected platform -- Definitions and configurations for types, signers, addresses, and chains -- Helpers configured for dealing with unsigned transactions on the selected platform - -These modules also import and expose essential functions and define types or constants from the chain's native ecosystem to reduce the dependencies needed to interact with a chain using Wormhole. Rather than installing the entire native package for each desired platform, you can install a targeted package of standardized functions and definitions essential to connecting with Wormhole, keeping project dependencies as slim as possible. - - -Wormhole currently supports the following platforms: - -- EVM -- Solana -- Cosmos -- Sui -- Aptos -- Algorand - -See the [Platforms folder of the TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms){target=\_blank} for an up-to-date list of the platforms supported by the Wormhole TypeScript SDK. - -### Chain Context - -The `definitions` package of the SDK includes the `ChainContext` class, which creates an interface for working with connected chains in a standardized way. This class contains the network, chain, and platform configurations for connected chains and cached RPC and protocol clients. The `ChainContext` class also exposes chain-specific methods and utilities. Much of the functionality comes from the `Platform` methods but some specific chains may have overridden methods via the context. This is also where the `Network`, `Chain`, and `Platform` type parameters which are used throughout the package are defined. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/get-chain.ts' -``` - -### Addresses - -The SDK uses the `UniversalAddress` class to implement the `Address` interface, which all address types must implement. Addresses from various networks are parsed into their byte representation and modified as needed to ensure they are exactly 32 bytes long. Each platform also has an address type that understands the native address formats, referred to as `NativeAddress.` These abstractions allow you to work with addresses consistently regardless of the underlying chain. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/addresses.ts' -``` - -### Tokens - -Similar to the `ChainAddress` type, the `TokenId` type provides the chain and address of a given token. The following snippet introduces `TokenId`, a way to uniquely identify any token, whether it's a standard token or a blockchain's native currency (like ETH for Ethereum). - -Wormhole uses their contract address to create a `TokenId` for standard tokens. For native currencies, Wormhole uses the keyword `native` instead of an address. This makes it easy to work with any type of token consistently. - -Finally, the snippet demonstrates how to convert a `TokenId` back into a regular address format when needed. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/tokens.ts' -``` - -### Signers - -Certain methods of signing transactions require a `Signer` interface in the SDK. Depending on the specific requirements, this interface can be fulfilled by either a `SignOnlySigner` or a `SignAndSendSigner`. A signer can be created by wrapping an offline or web wallet. - -A `SignOnlySigner` is used when the signer isn't connected to the network or prefers not to broadcast transactions themselves. It accepts an array of unsigned transactions and returns an array of signed and serialized transactions. Before signing, the transactions may be inspected or altered. It's important to note that the serialization process is chain-specific. Refer to the testing signers (e.g., [EVM](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/evm/src/signer.ts){target=\_blank} or [Solana](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/solana/src/signer.ts){target=\_blank}) for an example of how to implement a signer for a specific chain or platform. - -Conversely, a `SignAndSendSigner` is appropriate when the signer is connected to the network and intends to broadcast the transactions. This type of signer also accepts an array of unsigned transactions but returns an array of transaction IDs corresponding to the order of the unsigned transactions. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/signers.ts' -``` - -#### Set Up a Signer with Ethers.js - -To sign transactions programmatically with the Wormhole SDK, you can use Ethers.js to manage private keys and handle signing. Here's an example of setting up a signer using Ethers.js: - -```javascript ---8<-- 'code/build/toolkit/typescript-sdk/ethers.js' -``` - - - **`provider`** - responsible for connecting to the Ethereum network (or any EVM-compatible network). It acts as a bridge between your application and the blockchain, allowing you to fetch data, check the state of the blockchain, and submit transactions - - - **`signer`** - represents the account that will sign the transaction. In this case, you’re creating a signer using the private key associated with the account. The signer is responsible for authorizing transactions by digitally signing them with the private key - - - **`Wallet`** - combines both the provider (for blockchain interaction) and the signer (for transaction authorization), allowing you to sign and send transactions programmatically - -These components work together to create, sign, and submit a transaction to the blockchain. - -???- tip "Managing Private Keys Securely" - Handling private keys is unavoidable, so it’s crucial to manage them securely. Here are some best practices: - - - **Use environment variables** - avoid hardcoding private keys in your code. Use environment variables or secret management tools to inject private keys securely - - **Hardware wallets** - for production environments, consider integrating hardware wallets to keep private keys secure while allowing programmatic access through the SDK - -### Protocols - -While Wormhole is a Generic Message Passing (GMP) protocol, several protocols have been built to provide specific functionality. If available, each protocol will have a platform-specific implementation. These implementations provide methods to generate transactions or read state from the contract on-chain. - -#### Wormhole Core - -The core protocol underlies all Wormhole activity. This protocol is responsible for emitting the message containing the information necessary to perform bridging, including the [emitter address](https://docs.wormhole.com/wormhole/reference/glossary#emitter){target=\_blank}, the [sequence number](https://docs.wormhole.com/wormhole/reference/glossary#sequence){target=\_blank} for the message, and the payload of the message itself. - -The following example demonstrates sending and verifying a message using the Wormhole Core protocol on Solana. - -First, initialize a Wormhole instance for the Testnet environment, specifically for the Solana chain. Then, obtain a signer and its associated address, which will be used to sign transactions. - -Next, get a reference to the core messaging bridge, which is the main interface for interacting with Wormhole's cross-chain messaging capabilities. -The code then prepares a message for publication. This message includes: - -- The sender's address -- The message payload (in this case, the encoded string `lol`) -- A nonce (set to `0` here, but can be any user-defined value to uniquely identify the message) -- A [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} (set to `0`, which determines the finality requirements for the message) - -After preparing the message, the next steps are to generate, sign, and send the transaction or transactions required to publish the message on the Solana blockchain. Once the transaction is confirmed, the Wormhole message ID is extracted from the transaction logs. This ID is crucial for tracking the message across chains. - -The code then waits for the Wormhole network to process and sign the message, turning it into a Verified Action Approval (VAA). This VAA is retrieved in a `Uint8Array` format, with a timeout of 60 seconds. - -Lastly, the code will demonstrate how to verify the message on the receiving end. A verification transaction is prepared using the original sender's address and the VAA, and finally, this transaction is signed and sent. - -???+ code "View the complete script" - ```ts - --8<-- 'code/build/toolkit/typescript-sdk/example-core-bridge.ts' - ``` - -The payload contains the information necessary to perform whatever action is required based on the protocol that uses it. - -#### Token Bridge - -The most familiar protocol built on Wormhole is the Token Bridge. Every chain has a `TokenBridge` protocol client that provides a consistent interface for interacting with the Token Bridge, which includes methods to generate the transactions required to transfer tokens and methods to generate and redeem attestations. `WormholeTransfer` abstractions are the recommended way to interact with these protocols, but it is possible to use them directly. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/token-bridge-snippet.ts' -``` - -Supported protocols are defined in the [definitions module](https://github.com/wormhole-foundation/connect-sdk/tree/main/core/definitions/src/protocols){target=\_blank}. - -## Transfers - -While using the [`ChainContext`](#chain-context) and [`Protocol`](#protocols) clients directly is possible, the SDK provides some helpful abstractions for transferring tokens. - -The `WormholeTransfer` interface provides a convenient abstraction to encapsulate the steps involved in a cross-chain transfer. - -### Token Transfers - -Performing a token transfer is trivial for any source and destination chains. You can create a new `Wormhole` object to make objects like `TokenTransfer` and `CircleTransfer`, to transfer tokens between chains. - -The following example demonstrates the process of initiating and completing a token transfer. It starts by creating a `TokenTransfer` object, which tracks the transfer's state throughout its lifecycle. The code then obtains a quote for the transfer, ensuring the amount is sufficient to cover fees and any requested native gas. - -The transfer process is divided into three main steps: - -1. Initiating the transfer on the source chain -2. Waiting for the transfer to be attested (if not automatic) -3. Completing the transfer on the destination chain - -For automatic transfers, the process ends after initiation. The code waits for the transfer to be attested for manual transfers and then completes it on the destination chain. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/token-bridge.ts:120:158' -``` - -??? code "View the complete script" - ```ts hl_lines="122" - --8<-- 'code/build/toolkit/typescript-sdk/token-bridge.ts' - ``` - -Internally, this uses the [TokenBridge](#token-bridge) protocol client to transfer tokens. Like other Protocols, the `TokenBridge` protocol provides a consistent set of methods across all chains to generate a set of transactions for that specific chain. - -### Native USDC Transfers - -You can also transfer native USDC using [Circle's CCTP](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. Please note that if the transfer is set to `Automatic` mode, a fee for performing the relay will be included in the quote. This fee is deducted from the total amount requested to be sent. For example, if the user wishes to receive `1.0` on the destination, the amount sent should be adjusted to `1.0` plus the relay fee. The same principle applies to native gas drop offs. - -In the following example, the `wh.circleTransfer` function is called with several parameters to set up the transfer. It takes the amount to be transferred (in the token's base units), the sender's chain and address, and the receiver's chain and address. The function also allows specifying whether the transfer should be automatic, meaning it will be completed without further user intervention. - -An optional payload can be included with the transfer, though it's set to undefined in this case. Finally, if the transfer is automatic, you can request that native gas (the blockchain's native currency used for transaction fees) be sent to the receiver along with the transferred tokens. - -When waiting for the `VAA`, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will [vary by network](https://developers.circle.com/stablecoins/docs/required-block-confirmations#mainnet){target=\_blank}. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/cctp.ts:69:112' -``` - -??? code "View the complete script" - ```ts - --8<-- 'code/build/toolkit/typescript-sdk/cctp.ts' - ``` - -### Recovering Transfers - -It may be necessary to recover an abandoned transfer before it is completed. To do this, instantiate the `Transfer` class with the `from` static method and pass one of several types of identifiers. A `TransactionId` or `WormholeMessageId` may be used to recover the transfer. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/cctp.ts:120:126' -``` - -??? code "View the complete script" - ```ts hl_lines="130" - --8<-- 'code/build/toolkit/typescript-sdk/cctp.ts' - ``` - -## Routes - -While a specific `WormholeTransfer`, such as `TokenTransfer` or `CCTPTransfer`, may be used, the developer must know exactly which transfer type to use for a given request. - -To provide a more flexible and generic interface, the `Wormhole` class provides a method to produce a `RouteResolver` that can be configured with a set of possible routes to be supported. - -The following section demonstrates setting up and validating a token transfer using Wormhole's routing system. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/router.ts:24:31' -``` - -Once created, the resolver can be used to provide a list of input and possible output tokens. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/router.ts:33:53' -``` - -Once the tokens are selected, a `RouteTransferRequest` may be created to provide a list of routes that can fulfill the request. Creating a transfer request fetches the token details since all routes will need to know about the tokens. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/router.ts:55:67' -``` - -Choosing the best route is currently left to the developer, but strategies might include sorting by output amount or expected time to complete the transfer (no estimate is currently provided). - -After choosing the best route, extra parameters like `amount`, `nativeGasDropoff`, and `slippage` can be passed, depending on the specific route selected. A quote can be retrieved with the validated request. - -After successful validation, the code requests a transfer quote. This quote likely includes important details such as fees, estimated time, and the final amount to be received. If the quote is generated successfully, it's displayed for the user to review and decide whether to proceed with the transfer. This process ensures that all transfer details are properly set up and verified before any actual transfer occurs. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/router.ts:72:93' -``` - -Finally, assuming the quote looks good, the route can initiate the request with the quote and the `signer`. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/router.ts:100:106' -``` - -??? code "View the complete script" - - ```ts - --8<-- 'code/build/toolkit/typescript-sdk/router.ts' - ``` - -See the `router.ts` example in the [examples directory](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/examples){target=\_blank} for a full working example. - -### Routes as Plugins - -Routes can be imported from any npm package that exports them and configured with the resolver. Custom routes must extend [`Route`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L21-L64){target=\_blank} and implement [`StaticRouteMethods`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L101){target=\_blank}. - -```ts ---8<-- 'code/build/toolkit/typescript-sdk/custom-route.ts' -``` - -A noteworthy example of a route exported from a separate npm package is Wormhole Native Token Transfers (NTT). See the [`NttAutomaticRoute`](https://github.com/wormhole-foundation/native-token-transfers/blob/66f8e414223a77f5c736541db0a7a85396cab71c/sdk/route/src/automatic.ts#L48){target=\_blank} route implementation. - -## See Also - -The TSdoc is available [on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank}. diff --git a/build/transfers/.pages b/build/transfers/.pages deleted file mode 100644 index 05ffc8a56..000000000 --- a/build/transfers/.pages +++ /dev/null @@ -1,8 +0,0 @@ -title: Multichain Transfers -nav: - - index.md - - connect - - native-token-transfers - - settlement - - 'Token Bridge': 'token-bridge.md' - - 'CCTP Bridge': 'cctp.md' diff --git a/build/transfers/connect/.pages b/build/transfers/connect/.pages deleted file mode 100644 index 6bf304dd7..000000000 --- a/build/transfers/connect/.pages +++ /dev/null @@ -1,9 +0,0 @@ -title: Connect UI Widget -nav: - - index.md - - 'Overview': overview.md - - 'Routes': routes.md - - 'Features': features.md - - 'Configuration': configuration - - 'v1 Migration': upgrade.md - - 'FAQS': faqs.md \ No newline at end of file diff --git a/build/transfers/connect/configuration/.pages b/build/transfers/connect/configuration/.pages deleted file mode 100644 index 31cfbdf5a..000000000 --- a/build/transfers/connect/configuration/.pages +++ /dev/null @@ -1,5 +0,0 @@ -title: Connect Configuration -nav: - - index.md - - 'Data': configure-data.md - - 'Theme': configure-theme.md \ No newline at end of file diff --git a/build/transfers/connect/configuration/index.md b/build/transfers/connect/configuration/index.md deleted file mode 100644 index ed8f73b11..000000000 --- a/build/transfers/connect/configuration/index.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer ---- - -# Wormhole Connect - -## Configure Connect - -Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. - -This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. - -!!! note - To upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for instructions. - - If you're using an older version of Wormhole Connect (v0.x), please refer to the [v0.x configuration documentation](/docs/build/transfers/connect/configuration-v0/){target=\_blank}. - -
- -- :octicons-database-16:{ .lg .middle } **Data** - - --- - - Learn how to configure the networks, tokens, and routes supported by Wormhole Connect. Set up RPC endpoints, whitelist tokens, and leverage multiple bridging protocols to meet your dApp's needs. - - - [:custom-arrow: Get started](/docs/build/transfers/connect/configuration/configure-data/) - -- :octicons-apps-16:{ .lg .middle } **Theme** - - --- - - Discover how to style the Wormhole Connect widget to align with your brand. Customize colors, fonts, and UI elements to deliver a seamless user experience. - - [:custom-arrow: Explore routes](/docs/build/transfers/connect/configuration/configure-theme/) - -
diff --git a/build/transfers/connect/index.md b/build/transfers/connect/index.md deleted file mode 100644 index 93e314c44..000000000 --- a/build/transfers/connect/index.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate multichain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer ---- - -# Wormhole Connect - -Wormhole Connect is a customizable widget that brings wrapped and native token cross-chain asset transfers into your dApp in as few as 3 lines of code. Connect is available as a React component or hosted version via CDN so you can easily configure any application to transfer tokens via Wormhole. - -## Build with Connect - -[timeline left(wormhole-docs/.snippets/text/build/transfers/connect/connect-timeline.json)] - -## See It In Action - -Wormhole Connect is deployed live in several production apps. Here are a few: - -- [Portal Bridge](https://portalbridge.com/){target=\_blank} -- [Jupiter](https://jup.ag/onboard/cctp){target=\_blank} -- [Pancake Swap](https://bridge.pancakeswap.finance/wormhole){target=\_blank} - -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} page to learn how to combine Connect with other Wormhole products, including Native Token Transfer (NTT). - -## Next Steps - -
- -- :octicons-tools-16:{ .lg .middle} **Get Started Now** - - --- - - Follow this series of how-to guides to integrate Connect into your React dApp and configure options to fit your user's needs. - - [:custom-arrow: Get started](/docs/build/transfers/connect/overview/#integrate-connect) - -- :octicons-tools-16:{ .lg .middle } **Multichain Swap** - - --- - - This tutorial guides you step-by-step through integrating Connect into your React dApp to transfer tokens from Sui to Avalanche Fuji. This tutorial is readily adaptable to work with other [supported networks](/docs/build/start-building/supported-networks/){target=\_blank}. - - - [:custom-arrow: Get started](/docs/tutorials/connect/react-dapp/) - - -- :octicons-tools-16:{ .lg .middle } **Connect FAQs** - - --- - - Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. - - [:custom-arrow: Visit FAQs](/docs/build/transfers/connect/faqs/) - -- :octicons-tools-16:{ .lg .middle } **Supported Features by Chain** - - --- - - Get a more detailed look at Wormhole Connect features with a breakdown of supported features by chain. - - [:custom-arrow: Supported Features](/docs/build/transfers/connect/features/) - -
- - - diff --git a/build/transfers/connect/overview.md b/build/transfers/connect/overview.md deleted file mode 100644 index bfadf259a..000000000 --- a/build/transfers/connect/overview.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Overview -description: Explore Wormhole Connect, the React widget that allows you to offer an easy-to-use UI for cross-chain asset transfers via Wormhole in a web application. -categories: Connect, Transfer ---- - -# Wormhole Connect - -## Introduction {: #introduction } - -Wormhole Connect is a React widget that lets developers offer an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. Check out the [Wormhole Connect GitHub repository](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. - -The [Wormhole TypeScript SDK](https://docs.wormhole.com/wormhole/reference/sdk-docs){target=\_blank} allows you to implement the same functionality as the Connect widget but in your own UI. Check out the docs for more information on using the SDK instead of Connect. - -## Features {: #features } - -Wormhole Connect is easy to customize to suit your application's needs. You can specify technical details like supported assets and custom RPCs or forgo customization and have a full-featured widget. The widget UI is highly customizable, with extensive styling options available, including a user-friendly no code styling interface for those who prefer a more visual approach to design. The features of Wormhole Connect include: - -- Multiple ways to bridge assets ([routes](/docs/build/transfers/connect/routes/){target=\_blank}) -- Extensive ways to style the UI (including the [no code styling interface](https://connect-in-style.wormhole.com/){target=\_blank}) -- Ways to [configure](/docs/build/transfers/connect/configuration/){target=\_blank} what feature set to offer -- Ability to configure any token to bridge via Wormhole -- [Ability to drop off some gas](/docs/build/transfers/connect/features/){target=\_blank} at the destination - -For more details about the features of Wormhole Connect and a breakdown of supported features by chain, be sure to check [the features page](/docs/build/transfers/connect/features/){target=\_blank}. - -## Integrate Connect {: #integrate-connect } - -### Import Directly into a React App {: #import-directly-into-a-react-app} - -First, install the Wormhole Connect npm package. You can read more about the package by clicking on the following button: [![npm version](https://img.shields.io/npm/v/@wormhole-foundation/wormhole-connect.svg)](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} - -```bash -npm i @wormhole-foundation/wormhole-connect -``` - -Now you can import the React component: - -```ts ---8<-- 'code/build/transfers/connect/overview/import-v1.js' -``` - -### Use Hosted Version via CDN {: #use-hosted-version-via-cdn} - -If you're not using React, you can still embed Connect on your website by using the hosted version. This uses pre-built packages (which include React) served from NPM by jsdelivr.net. - -```ts title="v1.x" ---8<-- 'code/build/transfers/connect/overview/hosted.js' -``` - -For help migrating from Connect v0.x to v1.x, see the [v1 Migration](/docs/build/transfers/connect/upgrade/){target=\_blank} guide. - -???- code "v0.x" - Simply copy and paste the following into your HTML body, and replace the ```INSERT_WORMHOLE_CONNECT_VERSION``` in the links with the most recent production version of Wormhole Connect. You can check what the most recent version is on [NPM](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/latest){target=\_blank}. - - ```html - --8<-- 'code/build/transfers/connect/overview/cdn.html' - ``` - - For example, for [0.3.13](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/0.3.13){target=\_blank}: - - ```html - --8<-- 'code/build/transfers/connect/overview/cdn-with-version.html' - ``` - -It is important to periodically update your Wormhole Connect instance to the latest version, as there are frequent functionality and security releases. - -## Configuration {: #configuration} - -This is just an overview of what's possible. Check the [Configuration docs](/docs/build/transfers/connect/configuration/){target=\_blank} for details about all the configuration options. - -The default configuration of Wormhole Connect may not be exactly what you're looking for. You may want to: - - - Use custom styles - - Restrict the chains that you allow in your app - - Add support for your project's token, and eliminate tokens you don't want to reduce noise - - Configuring custom RPC URLs (This is highly recommended as default public RPCs are heavily throttled) - - Restrict the [routes](/docs/build/transfers/connect/routes/){target=\_blank} that are available - -For additional information on the preceding options, check the [configuration options](/docs/build/transfers/connect/configuration/){target=\_blank} and customize your widget however you like. diff --git a/build/transfers/index.md b/build/transfers/index.md deleted file mode 100644 index 7ff0ea1ef..000000000 --- a/build/transfers/index.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Multichain Transfers -description: This section guides you through using Wormhole products to securely and efficiently transfer assets and messages across multiple blockchains. ---- - -# Multichain Transfers - -Wormhole transfer products offer multiple asset transfer options to meet developer needs and use cases. These sections include guides to integrate and use Wormhole transfer products to securely and efficiently transfer assets and messages across multiple blockchains. - -Use the following links to jump directly to each Wormhole transfer product page or continue on for a feature-based product comparison. - -- [**Connect**](/docs/build/transfers/connect/) - a pre-built bridging UI for cross-chain token transfers, requiring minimal setup -- [**Native Token Transfers (NTT)**](/docs/build/transfers/native-token-transfers/) - a mechanism to transfer native tokens cross-chain seamlessly without converting to a wrapped asset -- [**Token Bridge**](/docs/learn/transfers/token-bridge/) - a bridging solution that uses a lock and mint mechanism -- [**Settlement**](/docs/build/transfers/settlement/) - an intent protocol suite for fast multichain transfers, optimizing liquidity flows and interoperability without relying on traditional bridging methods - -## Products By Feature - -While all of these products handle token transfers, there are additional features to consider when selecting the best fit for your project needs. - -
- -- :octicons-file-code-16:{ .lg .middle } **Message Payload** - - --- - - Send message payloads for social platforms, NFTs, and more with Token Bridge's lock and mint wrapped token mechanism. - - [:custom-arrow: Discover Token Bridge](/docs/build/transfers/token-bridge/) - -- :octicons-file-code-16:{ .lg .middle } **Native Assets** - - --- - - Eliminate the need for wrapped tokens and issue native multichain assets with Native Token Transfers (NTT). - - [:custom-arrow: Discover Native Token Transfers](/docs/build/transfers/native-token-transfers/) - - -- :octicons-file-code-16:{ .lg .middle } **Speed at Scale** - - --- - - Unleash institutional-scale digital asset settlement with Wormhole Settlement's intent-based asset transfers and liquidity layer. - - [:custom-arrow: Discover Settlement](/docs/build/transfers/settlement/) - -- :octicons-gear-16:{ .lg .middle } **Plug-and-Play UI** - - --- - - Add Wormhole's bridge UI to your dApp, no smart contract development required, with Connect. - - [:custom-arrow: Discover Connect](/docs/build/transfers/connect/) - -
- -## Additional Resources - -
- -- :octicons-tools-16:{ .lg .middle } **Product Comparison** - - --- - - Compare Wormhole's cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. - - [:custom-arrow: Compare Products](/docs/build/start-building/products/) - -- :octicons-book-16:{ .lg .middle } **Use Cases** - - --- - - Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. - - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) - - -
diff --git a/build/transfers/native-token-transfers/.pages b/build/transfers/native-token-transfers/.pages deleted file mode 100644 index a3f09de77..000000000 --- a/build/transfers/native-token-transfers/.pages +++ /dev/null @@ -1,8 +0,0 @@ -title: Native Token Transfers -nav: - - index.md - - deployment-process - - 'NTT CLI Commands': 'cli-commands.md' - - configuration - - 'Managers and Transceivers': 'managers-transceivers.md' - - 'FAQS': faqs.md \ No newline at end of file diff --git a/build/transfers/native-token-transfers/cli-commands.md b/build/transfers/native-token-transfers/cli-commands.md deleted file mode 100644 index 6881c85ef..000000000 --- a/build/transfers/native-token-transfers/cli-commands.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: NTT CLI Commands -description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. -categories: NTT, Transfer ---- - -# NTT CLI Commands - -## Introduction - -The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. - -If you haven't installed the NTT CLI yet, follow the [NTT Installation Guide](/docs/build/transfers/native-token-transfers/deployment-process/installation/#installation){target=\_blank} to set it up before proceeding. - -## Table of Commands - -The following table lists the available NTT CLI commands, descriptions, and examples. - -To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. - -### General Commands - -| Command | Description | Examples | -|-----------------------------------------|-------------------------------------------------------|--------------------------| -| `ntt update` | update the NTT CLI | `ntt update` | -| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | -| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest`| -| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0`| -| `ntt clone
` | initialize a deployment file from an existing contract| `ntt clone Mainnet Solana Sol5678...`| -| `ntt init ` | initialize a deployment file | `ntt init devnet` | -| `ntt pull` | pull the remote configuration | `ntt pull` | -| `ntt push` | push the local configuration | `ntt push` | -| `ntt status` | check the status of the deployment | `ntt status` | - -### Configuration Commands - -| Command | Description | Examples | -|---------------------------------------------|----------------------------------------|-------------------------------------| -| `ntt config set-chain `| set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key`| -| `ntt config unset-chain ` | unset a configuration value for a chain| `ntt config unset-chain Ethereum scan_api_key`| -| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key`| - -### Solana Commands - -| Command | Description | Examples | -|-----------------------------------------------|---------------------------------------------------------|------------------| -| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json`| -| `ntt solana token-authority ` | print the token authority address for a given program ID| `ntt solana token-authority Sol1234...`| -| `ntt solana ata `| print the token authority address for a given program ID| `ntt solana ata Mint123... Owner123... token22`| - -## Where to Go Next - -
- - -- :octicons-gear-16:{ .lg .middle } **Configure NTT** - - --- - - Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - - [:custom-arrow: Configure your NTT deployment](/docs/build/transfers/native-token-transfers/configuration/) - -- :octicons-question-16:{ .lg .middle } **NTT FAQs** - - --- - - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. - - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) - -
diff --git a/build/transfers/native-token-transfers/configuration/.pages b/build/transfers/native-token-transfers/configuration/.pages deleted file mode 100644 index 3cf9e420f..000000000 --- a/build/transfers/native-token-transfers/configuration/.pages +++ /dev/null @@ -1,5 +0,0 @@ -title: NTT Configuration -nav: - - index.md - - 'Rate Limiting': 'rate-limiting.md' - - 'Access Control': 'access-control.md' diff --git a/build/transfers/native-token-transfers/configuration/index.md b/build/transfers/native-token-transfers/configuration/index.md deleted file mode 100644 index ee32ef34b..000000000 --- a/build/transfers/native-token-transfers/configuration/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Native Token Transfers (NTT) - Configuration -description: This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -categories: NTT, Transfer ---- - -# Configure Native Token Transfers (NTT) - -## Get Started - -This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - -
- -- :octicons-clock-16:{ .lg .middle } **Rate Limiting** - - --- - - Discover options for configuring rate limits and how queueing effects transaction flow. - - [:custom-arrow: Explore rate limit options](/docs/build/transfers/native-token-transfers/configuration/rate-limiting/) - -- :octicons-unlock-16:{ .lg .middle } **Access Control** - - --- - - Learn more about access control, including why you should consider setting a separate Pauser address as part of your development security plan. - - [:custom-arrow: Explore access control roles](/docs/build/transfers/native-token-transfers/configuration/access-control/) - -
diff --git a/build/transfers/native-token-transfers/deployment-process/.pages b/build/transfers/native-token-transfers/deployment-process/.pages deleted file mode 100644 index f3efbd38f..000000000 --- a/build/transfers/native-token-transfers/deployment-process/.pages +++ /dev/null @@ -1,9 +0,0 @@ -title: Deployment Process -nav: - - index.md - - 'Installation': 'installation.md' - - 'Deploy to EVM': 'deploy-to-evm.md' - - 'Deploy to EVM via Launchpad': 'evm-launchpad.md' - - 'Deploy to Solana': 'deploy-to-solana.md' - - 'Post Deployment': 'post-deployment.md' - - 'Troubleshooting': 'troubleshooting.md' \ No newline at end of file diff --git a/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md b/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md deleted file mode 100644 index c88e45d2d..000000000 --- a/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Native Token Transfers EVM Deployment -description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. -categories: NTT, Transfer ---- - -# Native Token Transfers (NTT) EVM Development - -## Deploy Your Token and Ensure Compatibility - -If you still need to do so, deploy the token contract to the destination or spoke chains. - -### Requirements for Token Deployment - -Wormhole’s NTT is an open framework that supports various deployment modes. The NTT CLI currently supports two deployment modes: burn-and-mint and hub-and-spoke. These modes differ in how tokens are managed across chains. - -#### Burn-and-Mint Mode - -Tokens integrated with `NttManager` in `burning` mode require the following two functions to be present: - -- `burn(uint256 amount)` -- `mint(address account, uint256 amount)` - -These functions aren't part of the standard ERC-20 interface. The [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} documents the required functions and convenience methods, errors, and events. - -??? code "View the complete `INttToken` Interface`" - ```solidity - --8<-- 'code/build/transfers/native-token-transfers/deployment-process/INttToken.sol' - ``` - -Later, you set mint authority to the corresponding `NttManager` contract. You can also follow the scripts in the [example NTT token](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} repository to deploy a token contract. - -#### Hub-and-Spoke Mode - -A central hub chain (e.g., Ethereum) manages the total token supply in hub-and-spoke mode. Other chains (spokes) mint or burn tokens during cross-chain transfers, ensuring consistency with the locked tokens on the hub chain. - - - **Hub chain** - tokens are locked on the hub chain when transferring to spoke chains - - **Spoke chains** - tokens are native to the spoke chains and are either minted or burned during cross-chain transfers - -!!! note - The only requirement for using the NTT framework is an ERC20 token, which can be newly deployed or existing. Steps like setting mint authority apply only to spoke chains. - -For example, when transferring tokens from Ethereum (hub) to Polygon (spoke), the NTT Manager locks tokens on Ethereum, and the corresponding amount is minted on Polygon. Similarly, transferring tokens back from Polygon to Ethereum burns the tokens on Polygon and unlocks the equivalent tokens on Ethereum. - -This process ensures that the total token supply remains consistent across all chains, with the hub chain acting as the source of truth. - -For more detailed information, see the [Deployment Models](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank} page. - -### Key Differences Between Modes - - - **Burn-and-mint** - tokens must implement custom `mint` and `burn` functions, allowing each chain to manage token issuance independently - - **Hub-and-spoke** - tokens only need to be ERC20 compliant, with the hub chain acting as the source of truth for supply consistency - -## Deploy NTT - -Create a new NTT project: - -```bash -ntt new my-ntt-deployment -cd my-ntt-deployment -``` - -Initialize a new `deployment.json` file specifying the network: - -=== "Testnet" - - ```bash - ntt init Testnet - ``` - -=== "Mainnet" - - ```bash - ntt init Mainnet - ``` - -Ensure you have set up your environment correctly: - -```bash -export ETH_PRIVATE_KEY=INSERT_PRIVATE_KEY -``` - -Add each chain you'll be deploying to. The following example demonstrates configuring NTT in burn-and-mint mode on Ethereum Sepolia and Arbitrum Sepolia: - -```bash ---8<-- 'code/build/transfers/native-token-transfers/deployment-process/initialize.txt' -``` - -While not recommended, you can pass the `-skip-verify` flag to the `ntt add-chain` command if you want to skip contract verification. - -The `ntt add-chain` command takes the following parameters: - -- Name of each chain -- Version of NTT to deploy (use `--latest` for the latest contract versions) -- Mode (either `burning` or `locking`) -- Your token contract address - -The NTT CLI prints detailed logs and transaction hashes, so you can see exactly what's happening under the hood. - -## Configure NTT - -The NTT CLI takes inspiration from [git](https://git-scm.com/){target=\_blank}. You can run: - -- `ntt status` - checks whether your `deployment.json` file is consistent with what is on-chain -- `ntt pull` - syncs your `deployment.json` file with the on-chain configuration and set up rate limits with the appropriate number of decimals, depending on the specific chain. For example: - - For Solana, the limits are set with 9 decimal places: - ```json - "inbound": { - "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana - } - ``` - - For Sepolia (Ethereum Testnet), the limits are set with 18 decimal places: - ```json - "inbound": { - "Solana": "1000.000000000000000000" // inbound limit from Solana to Sepolia - } - ``` - - This initial configuration ensures that the rate limits are correctly represented for each chain's token precision - -- `ntt push` - syncs the on-chain configuration with local changes made to your `deployment.json` file - -After you deploy the NTT contracts, ensure that the deployment is properly configured and your local representation is consistent with the actual on-chain state by running `ntt status` and following the instructions shown on the screen. - -## Set Token Minter to NTT Manager - -The final step in the deployment process is to set the NTT Manager as a minter of your token on all chains you have deployed to in `burning` mode. When performing a hub-and-spoke deployment, it is only necessary to set the NTT Manager as a minter of the token on each spoke chain. - -!!! note - The required NTT Manager address can be found in the `deployment.json` file. - -- If you followed the [`INttToken`](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} interface, you can execute the `setMinter(address newMinter)` function - ```json - cast send $TOKEN_ADDRESS "setMinter(address)" $NTT_MANAGER_ADDRESS --private-key $ETH_PRIVATE_KEY --rpc-url $YOUR_RPC_URL - ``` - -- If you have a custom process to manage token minters, you should now follow that process to add the corresponding NTT Manager as a minter - -By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. - -!!!important - To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} page. \ No newline at end of file diff --git a/build/transfers/native-token-transfers/deployment-process/index.md b/build/transfers/native-token-transfers/deployment-process/index.md deleted file mode 100644 index 6f9323b8b..000000000 --- a/build/transfers/native-token-transfers/deployment-process/index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Native Token Transfers (NTT) - Deployment -description: This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. -categories: NTT, Transfer ---- - -# Deploy Native Token Transfers (NTT) - -## Get Started - -This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. - -
- -- :octicons-download-16:{ .lg .middle } **Installation** - - --- - - Prerequisites and commands for installing the NTT CLI and working with the NTT framework. - - [:custom-arrow: Install the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** - - --- - - Find information on preparing for NTT deployment to EVM, including an example NTT token repository. - - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains via Launchpad** - - --- - - Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. - - [:custom-arrow: Deploy via Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** - - --- - - Your guide to NTT deployment to Solana, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) - -- :octicons-search-16:{ .lg .middle } **Post Deployment** - - --- - - Learn how to best monitor and maintain your NTT deployment to get the most out of your Wormhole integration while providing security for users. - - [:custom-arrow: Explore next steps](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) - -- :octicons-alert-16:{ .lg .middle } **Troubleshooting** - - --- - - Explore solutions and detailed guidance in our troubleshooting guide to resolve issues with NTT deployment. - - [:custom-arrow: Get help](/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/) - -
diff --git a/build/transfers/native-token-transfers/deployment-process/installation.md b/build/transfers/native-token-transfers/deployment-process/installation.md deleted file mode 100644 index 389c43327..000000000 --- a/build/transfers/native-token-transfers/deployment-process/installation.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Native Token Transfers Installation -description: Learn how to Install Wormhole’s Native Token Transfers (NTT) framework, a flexible and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- - -# Install the Native Token Transfers CLI - -In this video, the Wormhole team walks you through installing the [Native Token Transfers (NTT) CLI](https://github.com/wormhole-foundation/native-token-transfers/tree/main/cli){target=\_blank}. You’ll see a practical demonstration of running commands, verifying your installation, and addressing common issues that might arise. If you prefer to follow written instructions or want a quick reference for each step, scroll down for the detailed installation guide. - -To start using the NTT CLI, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. - -
- -## Install NTT CLI - -The fastest way to deploy Native Token Transfers (NTT) is using the NTT CLI. As prerequisites, ensure you have the following installed: - -- Install [Bun](https://bun.sh/docs/installation){target=\_blank} - -Follow these steps to install the NTT CLI: - -1. Run the installation command in your terminal: - - ```bash - curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash - ``` - -2. Verify the NTT CLI is installed: - - ```bash - ntt --version - ``` - -3. Once installed, check out the available [NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/){target=\_blank} to start using the CLI - -## Update NTT CLI - -To update an existing NTT CLI installation, run the following command in your terminal: - -```bash -ntt update -``` - -NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. - -For local development, you can update your CLI version from a specific branch or install from a local path. - -To install from a specific branch, run: - -```bash -ntt update --branch foo -``` - -To install locally, run: -```bash -ntt update --path path/to/ntt/repo -``` - -Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. - -## Where to Go Next - -
- - -- :octicons-tools-16:{ .lg .middle } **Deploy to EVM Chains** - - --- - - Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to EVM chains](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) - -- :octicons-tools-16:{ .lg .middle } **Deploy to Solana** - - --- - - Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to Solana](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) - -
diff --git a/build/transfers/native-token-transfers/index.md b/build/transfers/native-token-transfers/index.md deleted file mode 100644 index 360c38107..000000000 --- a/build/transfers/native-token-transfers/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Native Token Transfers (NTT) -description: This section provides comprehensive guidance on configuring, deploying, and managing your Native Token Transfers (NTT) integration. -categories: NTT, Transfer ---- - -# Native Token Transfers - -Native Token Transfers (NTT) simplifies and enables seamless, flexible token transfers across blockchains. This section provides comprehensive guidance on configuring, deploying, and managing your NTT integration. It includes information relevant to both new token deployments and existing token management. - -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} and [Product Comparison](/docs/build/start-building/products/){target=\_blank} pages for help determining if NTT will meet the needs of your project. - -## Quickstart - -If needed, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. - -The process for creating, deploying, and monitoring NTTs is as follows. Select the title of each step to view the associated guide: - -[timeline left(wormhole-docs/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json)] - -## Deploy NTTs with Launchpad - -If you are deploying to EVM blockchains, the [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT. NTT Launchpad replaces manually deploying contracts or configuring relayers for each supported EVM chain. - -Follow the [Deploy NTT with Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/){target=\_blank} guide to create new multichain tokens or integrate existing tokens with just a few clicks. - -## Additional Resources - -
- -- :octicons-gear-16:{ .lg .middle } **NTT CLI Commands** - - --- - - The NTT CLI tool provides a comprehensive set of commands for creating, configuring, deploying, and monitoring NTTs. This page provides a comprehensive list of available NTT CLI commands, their descriptions, and examples to help you interact effectively with the NTT system. - - [:custom-arrow: NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/) - -- :octicons-question-16:{ .lg .middle } **NTT FAQs** - - --- - - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. - - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) - -
diff --git a/build/transfers/settlement/.pages b/build/transfers/settlement/.pages deleted file mode 100644 index f4b6a88b6..000000000 --- a/build/transfers/settlement/.pages +++ /dev/null @@ -1,6 +0,0 @@ -title: Wormhole Settlement -nav: - - index.md - - 'Build on the Wormhole Liquidity Layer': 'liquidity-layer.md' - - 'Run a Wormhole Settlement Solver': 'solver.md' - - 'FAQs': 'faqs.md' diff --git a/build/transfers/settlement/index.md b/build/transfers/settlement/index.md deleted file mode 100644 index a2954a26a..000000000 --- a/build/transfers/settlement/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Wormhole Settlement -description: Start building with Wormhole Settlement; integrate with the Liquidity Layer and set up Solvers to enable seamless cross-chain asset transfers. -categories: Settlement, Transfer ---- - -# Wormhole Settlement - -## Get Started - -This section provides resources to build with Wormhole Settlement, including integrating the Liquidity Layer into your application and running a Solver for efficient cross-chain asset transfers. - -
- -- :octicons-code-16:{ .lg .middle } **Build on the Liquidity Layer** - - --- - - Integrate seamlessly with Wormhole's Liquidity Layer, learn key EVM contract functions for fast and secure cross-chain transfers. - - [:custom-arrow: Build on the Liquidity layer](/docs/build/transfers/settlement/liquidity-layer/) - -- :octicons-code-16:{ .lg .middle } **Run a Settlement Solver** - - --- - - Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. - - [:custom-arrow: Run a Solver](/docs/build/transfers/settlement/solver/) - -
\ No newline at end of file diff --git a/build/transfers/settlement/liquidity-layer.md b/build/transfers/settlement/liquidity-layer.md deleted file mode 100644 index f00fa74fb..000000000 --- a/build/transfers/settlement/liquidity-layer.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Wormhole Settlement Liquidity Layer -description: Learn how to build on the Wormhole Liquidity Layer, the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. -categories: Settlement, Transfer ---- - -# Build on the Wormhole Liquidity Layer - -## Introduction - -The Wormhole Liquidity Layer is the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. It allows these protocols to bundle call data containing arbitrary actions that can be executed atomically alongside each transfer. This feature enables developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. The following section describes the key smart contract components for teams seeking to build atop Wormhole Settlement. - -## EVM Functions - -The EVM Token Router is a simple interface against which to integrate. For an integrator, the contracts have two main entry points: `placeMarketOrder` and `placeFastMarketOrder`. - -See the complete list of [Token Router contract addresses](/docs/build/reference/contract-addresses/#settlement-token-router){target=\_blank} for supported networks. - -### Fast Market Order - -The `placeFastMarketOrder` function allows the caller to elect for a _faster-than-finality_ transfer of USDC (with an arbitrary message payload) to the destination chain by setting the `maxFee` and `deadline` parameters. Using this interface does not guarantee that the caller's transfer will be delivered faster than finality; however, any willing market participants can compete for the specified `maxFee` by participating in an auction on the Solana `MatchingEngine` - -```solidity title="`placeFastMarketOrder` Interface" ---8<-- 'code/build/transfers/settlement/placeFastMarketOrder.sol' -``` - -??? interface "Parameters `placeFastMarketOrder()`" - - `amountIn` ++"uint128"++ - - The amount to transfer. - - --- - - `targetChain` ++"uint16"++ - - Target chain ID. - - --- - - `redeemer` ++"bytes32"++ - - Redeemer contract address. - - --- - - `redeemerMessage` ++"bytes"++ - - An arbitrary payload for the redeemer. - - --- - - `maxFee` ++"uint128"++ - - The maximum fee the user wants to pay to execute a fast transfer. - - --- - - `deadline` ++"uint32"++ - - The deadline for the fast transfer auction to start. Note: This timestamp should be for the `MatchingEngine` chain (such as Solana) to avoid any clock drift issues between different blockchains. Integrators can set this value to `0` if they don't want to use a deadline. - -The `placeFastMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. - -### Market Order - -The `placeMarketOrder` function is a _wait-for-full-finality_ USDC transfer with an arbitrary message payload. The Swap Layer, built on top of the Wormhole Settlement, uses this function if the auction on the matching engine for `placeFastMarketOrder` doesn't start within a specific deadline. - -```solidity title="`placeMarketOrder` Interface" ---8<-- 'code/build/transfers/settlement/placeMarketOrder.sol' -``` - -??? interface "Parameters `placeMarketOrder()`" - - `amountIn` ++"uint128"++ - - The amount to transfer. - - --- - - `targetChain` ++"uint16"++ - - Target chain ID. - - --- - - `redeemer` ++"bytes32"++ - - Redeemer contract address. - - --- - - `redeemerMessage` ++"bytes"++ - - An arbitrary payload for the redeemer. - -The `placeMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. diff --git a/build/transfers/settlement/solver.md b/build/transfers/settlement/solver.md deleted file mode 100644 index ceaf90048..000000000 --- a/build/transfers/settlement/solver.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: Wormhole Settlement Solver -description: Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. -categories: Settlement, Transfer ---- - -# Run a Wormhole Settlement Solver - -## Introduction - -This page provides instructions on how to set up, configure, and run a Solver for Wormhole Settlement using the [example solver](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/update-solver-example/solver){target=\_blank}. - -A Solver is an off-chain agent responsible for: - -- Listening to cross-chain transfer requests sent over Wormhole -- Bidding in auctions (on Solana) to fulfill each request -- Facilitating the actual cross-chain transfer by locking/burning assets on Solana and minting/unlocking them on the destination chain -- Rebalancing once the origin chain transaction finalizes and is redeemed back on Solana - -For information on how the protocol functions and its core features, please visit the [Wormhole Settlement](/docs/learn/transfers/settlement/overview/){target=\_blank} page. - -## Background - -The Solana Matching Engine's permissionless English auction is a central component of Wormhole Settlement protocol architecture. The Matching Engine contract allows any third-party solver to interact with the matching engine to place bids or improve existing ones. The contract includes four key instructions: - -1. `initialize_auction` - creates a new auction account on-chain and sets basic parameters like the auction's token mint, the amount required, and the bidding period details -2. `bid` - allows a solver to place or update a bid on the active auction -3. `finalize_auction` - following the conclusion of the auction, this instruction completes the fast transfer by sending funds to the recipient on the target chain. This instruction may call the Circle CCTP contract or release an NTT contract in the future, depending on the shuttle asset in question. Failure to execute this message within a predefined grace period may result in a penalty for the winning bidder. -4. `cancel_auction` - cancels an open auction when the auction is no longer valid or was created by mistake. The program returns all locked funds to their respective owners - -These instructions work together to carry out the auction as follows: - -- The solver transfers the bid amount to the program escrow account, which ensures they have liquidity -- With each successful call of `bid`, the program updates the auction to the new highest bidder, and the prior bid is atomically sent back to the originating solver -- The originating solver can repurpose the returned funds and use them to improve their bid -- Following the auction, the winning solver has to call an instruction on the matching engine to execute the intent - -When placing a bid, whether initial or improved, the solver must deposit the required funds plus a security deposit into the matching engine contract. In this permissionless auction, the requirement of this principal amount plus the security deposit ensures a solver's credible commitment to fulfill the transfer. Malicious actors could place hollow bids without this safeguard, undermining the auction's credibility and hindering true price discovery. - -If the winning solver fails to call the `finalize_auction` instruction, other competing solvers may permissionlessly 'slash' the solver by executing the instruction on their behalf and collecting a portion of the original security deposit as a reward. The remaining portion is routed to the user as compensation for the unanticipated delay. This mechanism properly incentivizes timely execution through solver redundancy and competition. - -## Testnet Example Solver - -You can clone the Wormhole [`example-liquidity-layer`](https://github.com/wormholelabs-xyz/example-liquidity-layer){target=\_blank} repository to use the included [`solver`](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/main/solver){target=\_blank} directory as an example solver to fulfill fast orders by interacting with the Matching Engine on Solana. - -!!!warning - This example is not optimized for performance, has only been tested on Solana devnet, and is not intended for production use. Any assumptions made in this example may not translate to mainnet. - -### Prerequisites - -In order to build and install dependencies locally in this repo, you will need: - -- node v20.18.1 -- npmv - get started by installing `nvm` using this [installation guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating){target=\_blank} - -Navigate into the `solver` directory, then run the command below to set up your environment and install the node dependencies and Matching Engine package: - -```sh -make dependencies -``` - -### Set up Config - -The following is an example of a `config.json` file for Solana devnet. The keys here are required for both the publisher and example solver processes. - -```json title="config.json" ---8<-- 'code/build/transfers/settlement/solver-config.json' -``` - -The rollback risks and offer edges configured in the sample config are arbitrary placeholders. You should use historical data and your risk tolerance, to determine appropriate values for your project. - -### Listen to Activity - -The example solver listens to attested Wormhole messages (VAAs) published on the Wormhole Guardian gossip network. To listen to this gossip network and run the VAA publisher, run the command below. Docker compose is used to listen to the Pyth Beacon and start the [`publishActivity`](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/publishActivity.ts){target=\_blank} process. - -```sh -NETWORK=testnet CONFIG=path/to/config.json make run-publisher -``` - -You should see output resembling: - -
- Start logging with info level. - 2025-01-21 16:38:28.145 [publisher] info: Environment: Testnet - 2025-01-21 16:38:36.631 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33635, vaaTime=1737499116 - 2025-01-21 16:38:51.044 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33637, vaaTime=1737499130 - 2025-01-21 16:40:24.890 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33639, vaaTime=1737499224 -
- -To set up the Pyth Beacon (which is run using make `run-publisher`), you may need to increase the UDP buffer size for the OS: - -=== "Linux" - - ```sh - sudo sysctl -w net.core.rmem_max=2097152 - sudo sysctl -w net.core.rmem_default=2097152 - ``` - -=== "MacOS" - - ```sh - sudo sysctl -w net.inet.udp.recvspace=2097152 - ``` - -### Running the Example Solver - -Using the same config for your publisher, run the example solver with the command below. - -```sh -CONFIG=path/to/config.json make run-solver -``` - -It is recommended you write log output to a file so errors can be tracked. The example config above specifies an example log filename. - -This process reads the following environment variables: - -```sh -SOLANA_PRIVATE_KEY_1= -SOLANA_PRIVATE_KEY_2= -SOLANA_PRIVATE_KEY_3= -SOLANA_PRIVATE_KEY_4= -SOLANA_PRIVATE_KEY_5= -``` - -At least one of these environment variables must be defined as a keypair encoded in base64 format. These payers must have SOL to send transactions on Solana devnet. If they need funds, they can request them from the [Solana devnet faucet](https://faucet.solana.com/){target=\_blank}. - -The example solver assumes that these payers own USDC Associated Token Accounts(ATAs), which will be used to fulfill fast transfers. These ATAs must be funded with Solana Devnet USDC. If your ATAs need funds, request some at the [Circle testnet faucet](https://faucet.circle.com/){target=\_blank}. - -Wallets and their corresponding ATA will be disabled if there are insufficient funds to pay for transactions or fulfill fast transfers. These constraints can be modified using the `updatePayerMinimumLamports` and `updateTokenMinimumBalance` methods. - -An address lookup table is required to execute some transactions. Use the command below to create one. - -```sh -CONFIG=path/to/config.json make create-lut -``` - -`SOLANA_PRIVATE_KEY_1` must be defined for this script to work. - -The example solver has the following toggles depending on which orders you want to fulfill: - -- `enableCctpOrderPipeline()` -- `enableLocalOrderPipeline()` -- `enablePlaceInitialOffer()` -- `enableImproveOffer()` - -See the comments in [runExampleSolver](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/runExampleSolver.ts){target=\_blank} for more information. - -This example solver does NOT do the following: - -- Discriminate between the CCTP source networks. You must add logic to determine whether you want to constrain fulfilling orders from specific networks. This solver will try to fulfill all orders as long as `enableCctpOrderPipeline()` is called -- Discriminate among fulfillment sizes. No logic determines how small or large fast order transfer sizes should be. This solver will try to fulfill anything as long as your balance can handle it -- Add auctions to auction history. We recommend that after settling a complete auction (one that you have won), you write the auction pubkey to a database and have a separate process to add auction history entries to reclaim rent from these auction accounts. The auction history time delay is two hours after the VAA timestamp. This example does not prescribe any specific database, so add whichever you want - - diff --git a/images/build/queries/overview/overview-1.webp b/images/build/queries/overview/overview-1.webp deleted file mode 100644 index 7a8c8b7f8..000000000 Binary files a/images/build/queries/overview/overview-1.webp and /dev/null differ diff --git a/images/learn/governance/multigov-detailed.webp b/images/learn/governance/multigov-detailed.webp deleted file mode 100644 index fb057501d..000000000 Binary files a/images/learn/governance/multigov-detailed.webp and /dev/null differ diff --git a/images/learn/governance/multigov-high-level.webp b/images/learn/governance/multigov-high-level.webp deleted file mode 100644 index f265146ca..000000000 Binary files a/images/learn/governance/multigov-high-level.webp and /dev/null differ diff --git a/images/learn/transfers/settlement/architecture/architecture-2.webp b/images/learn/transfers/settlement/architecture/architecture-2.webp deleted file mode 100644 index b5f218b77..000000000 Binary files a/images/learn/transfers/settlement/architecture/architecture-2.webp and /dev/null differ diff --git a/images/learn/transfers/token-bridge/token-bridge-diagram.webp b/images/learn/transfers/token-bridge/token-bridge-diagram.webp deleted file mode 100644 index cb3df65eb..000000000 Binary files a/images/learn/transfers/token-bridge/token-bridge-diagram.webp and /dev/null differ diff --git a/images/tutorials/connect/react-dapp/connect-1.webp b/images/products/connect/tutorials/react-dapp/connect-1.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-1.webp rename to images/products/connect/tutorials/react-dapp/connect-1.webp diff --git a/images/tutorials/connect/react-dapp/connect-2.webp b/images/products/connect/tutorials/react-dapp/connect-2.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-2.webp rename to images/products/connect/tutorials/react-dapp/connect-2.webp diff --git a/images/tutorials/connect/react-dapp/connect-3.webp b/images/products/connect/tutorials/react-dapp/connect-3.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-3.webp rename to images/products/connect/tutorials/react-dapp/connect-3.webp diff --git a/images/tutorials/connect/react-dapp/connect-4.webp b/images/products/connect/tutorials/react-dapp/connect-4.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-4.webp rename to images/products/connect/tutorials/react-dapp/connect-4.webp diff --git a/images/tutorials/connect/react-dapp/connect-5.webp b/images/products/connect/tutorials/react-dapp/connect-5.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-5.webp rename to images/products/connect/tutorials/react-dapp/connect-5.webp diff --git a/images/tutorials/connect/react-dapp/connect-6.webp b/images/products/connect/tutorials/react-dapp/connect-6.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-6.webp rename to images/products/connect/tutorials/react-dapp/connect-6.webp diff --git a/images/tutorials/connect/react-dapp/connect-7.webp b/images/products/connect/tutorials/react-dapp/connect-7.webp similarity index 100% rename from images/tutorials/connect/react-dapp/connect-7.webp rename to images/products/connect/tutorials/react-dapp/connect-7.webp diff --git a/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp b/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp new file mode 100644 index 000000000..f6ebe452f Binary files /dev/null and b/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp differ diff --git a/images/products/messaging/get-started/messaging-get-started01.webp b/images/products/messaging/get-started/messaging-get-started01.webp new file mode 100644 index 000000000..96435c302 Binary files /dev/null and b/images/products/messaging/get-started/messaging-get-started01.webp differ diff --git a/images/build/core-messaging/wormhole-relayers/relayer-1.webp b/images/products/messaging/guides/wormhole-relayers/relayer-1.webp similarity index 100% rename from images/build/core-messaging/wormhole-relayers/relayer-1.webp rename to images/products/messaging/guides/wormhole-relayers/relayer-1.webp diff --git a/images/products/multigov/concepts/architecture/architecture-1.webp b/images/products/multigov/concepts/architecture/architecture-1.webp new file mode 100644 index 000000000..1dbd578a7 Binary files /dev/null and b/images/products/multigov/concepts/architecture/architecture-1.webp differ diff --git a/images/products/multigov/concepts/architecture/architecture-2.webp b/images/products/multigov/concepts/architecture/architecture-2.webp new file mode 100644 index 000000000..f9ba5d9dd Binary files /dev/null and b/images/products/multigov/concepts/architecture/architecture-2.webp differ diff --git a/images/learn/transfers/native-token-transfers/architecture/architecture-1.webp b/images/products/native-token-transfers/concepts/architecture/architecture-1.webp similarity index 100% rename from images/learn/transfers/native-token-transfers/architecture/architecture-1.webp rename to images/products/native-token-transfers/concepts/architecture/architecture-1.webp diff --git a/images/learn/transfers/native-token-transfers/architecture/architecture-2.webp b/images/products/native-token-transfers/concepts/architecture/architecture-2.webp similarity index 100% rename from images/learn/transfers/native-token-transfers/architecture/architecture-2.webp rename to images/products/native-token-transfers/concepts/architecture/architecture-2.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp diff --git a/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp b/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp similarity index 100% rename from images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp rename to images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp diff --git a/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp b/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp new file mode 100644 index 000000000..477096e31 Binary files /dev/null and b/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp differ diff --git a/images/products/queries/overview/overview-1.webp b/images/products/queries/overview/overview-1.webp new file mode 100644 index 000000000..f43d3c85a Binary files /dev/null and b/images/products/queries/overview/overview-1.webp differ diff --git a/images/learn/transfers/settlement/architecture/architecture-1.webp b/images/products/settlement/concepts/architecture/architecture-1.webp similarity index 100% rename from images/learn/transfers/settlement/architecture/architecture-1.webp rename to images/products/settlement/concepts/architecture/architecture-1.webp diff --git a/images/products/settlement/concepts/architecture/architecture-2.webp b/images/products/settlement/concepts/architecture/architecture-2.webp new file mode 100644 index 000000000..549337e96 Binary files /dev/null and b/images/products/settlement/concepts/architecture/architecture-2.webp differ diff --git a/images/learn/transfers/settlement/architecture/architecture-3.webp b/images/products/settlement/concepts/architecture/architecture-3.webp similarity index 100% rename from images/learn/transfers/settlement/architecture/architecture-3.webp rename to images/products/settlement/concepts/architecture/architecture-3.webp diff --git a/images/tutorials/multichain-assets/multichain-tokens/multichain-token-1.webp b/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-1.webp similarity index 100% rename from images/tutorials/multichain-assets/multichain-tokens/multichain-token-1.webp rename to images/products/token-bridge/tutorials/multichain-tokens/multichain-token-1.webp diff --git a/images/tutorials/multichain-assets/multichain-tokens/multichain-token-2.webp b/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-2.webp similarity index 100% rename from images/tutorials/multichain-assets/multichain-tokens/multichain-token-2.webp rename to images/products/token-bridge/tutorials/multichain-tokens/multichain-token-2.webp diff --git a/images/tutorials/multichain-assets/multichain-tokens/multichain-token-3.webp b/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-3.webp similarity index 100% rename from images/tutorials/multichain-assets/multichain-tokens/multichain-token-3.webp rename to images/products/token-bridge/tutorials/multichain-tokens/multichain-token-3.webp diff --git a/images/tutorials/multichain-assets/multichain-tokens/multichain-token-4.webp b/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-4.webp similarity index 100% rename from images/tutorials/multichain-assets/multichain-tokens/multichain-token-4.webp rename to images/products/token-bridge/tutorials/multichain-tokens/multichain-token-4.webp diff --git a/images/tutorials/multichain-assets/multichain-tokens/multichain-token-5.webp b/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-5.webp similarity index 100% rename from images/tutorials/multichain-assets/multichain-tokens/multichain-token-5.webp rename to images/products/token-bridge/tutorials/multichain-tokens/multichain-token-5.webp diff --git a/images/learn/infrastructure/architecture/architecture-1.webp b/images/protocol/architecture/architecture-1.webp similarity index 100% rename from images/learn/infrastructure/architecture/architecture-1.webp rename to images/protocol/architecture/architecture-1.webp diff --git a/images/protocol/ecosystem/ecosystem-1.webp b/images/protocol/ecosystem/ecosystem-1.webp new file mode 100644 index 000000000..e446240a0 Binary files /dev/null and b/images/protocol/ecosystem/ecosystem-1.webp differ diff --git a/images/build/infrastructure/relayers/run-relayer/relayer-1.webp b/images/protocol/infrastructure-guides/run-relayer/relayer-1.webp similarity index 100% rename from images/build/infrastructure/relayers/run-relayer/relayer-1.webp rename to images/protocol/infrastructure-guides/run-relayer/relayer-1.webp diff --git a/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp b/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp similarity index 100% rename from images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp rename to images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp diff --git a/images/learn/introduction/introduction-1.webp b/images/protocol/introduction/introduction-1.webp similarity index 100% rename from images/learn/introduction/introduction-1.webp rename to images/protocol/introduction/introduction-1.webp diff --git a/learn/.pages b/learn/.pages deleted file mode 100644 index 30c9b84b9..000000000 --- a/learn/.pages +++ /dev/null @@ -1,11 +0,0 @@ -title: Learn -nav: - - index.md - - 'Introduction to Wormhole': 'introduction.md' -# TODO: Product Overview - - infrastructure - - transfers -# TODO: Queries - - governance - - 'Security': 'security.md' - - 'Glossary': 'glossary.md' diff --git a/learn/governance/.pages b/learn/governance/.pages deleted file mode 100644 index bbebe4687..000000000 --- a/learn/governance/.pages +++ /dev/null @@ -1,6 +0,0 @@ -title: Multichain Governance (MultiGov) -nav: - - index.md - - 'Overview': 'overview.md' - - 'Architecture': 'architecture.md' - - 'Theoretical FAQs': 'faq.md' \ No newline at end of file diff --git a/learn/governance/faq.md b/learn/governance/faq.md deleted file mode 100644 index 91a723e32..000000000 --- a/learn/governance/faq.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: MultiGov Theoretical FAQs -description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. -categories: MultiGov ---- - -# FAQs - -## General Questions - -### What is MultiGov? - -MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. It leverages Wormhole's interoperability infrastructure for seamless voting and proposal mechanisms across various chains. - -### How does MultiGov differ from traditional DAO governance? - -Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. - -### What are the main components of MultiGov? - -The main components of MultiGov include: - -- **Hub chain** - central coordination point for governance activities -- **Spoke chains** - additional chains where token holders can participate in governance -- **Wormhole integration** - enables secure cross-chain message passing -- **Governance token** - allows holders to participate in governance across all integrated chains diff --git a/learn/governance/index.md b/learn/governance/index.md deleted file mode 100644 index 070a23249..000000000 --- a/learn/governance/index.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Learn about MultiGov -description: Explore the MultiGov documentation for a comprehensive guide covering architecture, deployment, upgrading, integration, and FAQs. -categories: MultiGov ---- - -# MultiGov - -Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. Get an introduction to the core concepts, explore how the system's components work together, and find answers to common questions to help you navigate the platform effectively. - -## Get Started - -
- -- :octicons-book-16:{ .lg .middle } **Overview** - - --- - - Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. - - [:custom-arrow: Take a first glance at MultiGov](/docs/learn/governance/overview/) - -- :octicons-book-16:{ .lg .middle } **Architecture** - - --- - - Discover MultiGov's hub-and-spoke architecture, enabling EVM and Solana cross-chain governance through coordinated decision-making. - - [:custom-arrow: Learn about MultiGov architecture](/docs/learn/governance/architecture/) - -- :octicons-question-16:{ .lg .middle } **Theoretical FAQs** - - --- - - Find answers to common theoretical questions about MultiGov. - - [:custom-arrow: Find the answer to your theoretical questions](/docs/learn/governance/faq/) - -
- -## Next Steps - -
- -- :octicons-checklist-16:{ .lg .middle } **Begin the MultiGov Integration Process** - - --- - - Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. - - [:custom-arrow: Start the integration process now](/docs/build/multigov/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains** - - --- - - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. - - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** - - --- - - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. - - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) - -- :octicons-code-square-16:{ .lg .middle } **Tutorials** - - --- - - Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. - - [:custom-arrow: Create MultiGov solutions](/docs/tutorials/multigov/) - -- :octicons-question-16:{ .lg .middle } **Technical FAQs** - - --- - - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. - - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) - -
diff --git a/learn/governance/overview.md b/learn/governance/overview.md deleted file mode 100644 index 365003117..000000000 --- a/learn/governance/overview.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: MultiGov Overview -description: Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. -categories: MultiGov ---- - -# MultiGov: Cross-Chain Governance with Wormhole - -## Overview - -### What Is MultiGov and Why Is It Important? - -MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. By leveraging Wormhole's interoperability infrastructure, MultiGov enables seamless voting and proposal mechanisms across various chains. - -MultiGov is important because it: - -- **Increases participation** by allowing token holders from multiple chains to engage in governance -- **Enhances security** by leveraging Wormhole's robust cross-chain communication -- **Improves scalability** by integrating any chain supported by Wormhole -- **Enables unified governance** and coordinated decision-making across multiple networks - -### Key Features - -- **Hub and spoke model** - central coordination on a hub chain with participation from multiple spoke chains. A hub chain is where the governance state lives, while the spoke chains can be considered extensions of governance that allow for participation by token holders on other chains -- **Cross-chain voting** - token holders on any integrated chain can cast votes -- **Vote aggregation** - votes from all chains are collected and tallied on the hub -- **Cross-chain proposal execution** - approved proposals can be executed across multiple chains -- **Wormhole integration** - secure and reliable cross-chain communication -- **Flexible architecture** - can integrate with any Wormhole-supported blockchain - -### High-Level Architecture Diagram - -The diagram below represents MultiGov's high-level architecture, focusing on its hub-and-spoke model for decentralized governance across multiple chains. The hub chain acts as the central governance controller, managing proposal creation, vote tallying, and execution, while the spoke chains handle local voting and proposal execution on individual chains. The hub and spoke chains communicate via Wormhole's cross-chain messaging infrastructure, ensuring secure and efficient governance across multiple blockchain networks. - -For a deeper understanding of the system's structure and how the components interact, refer to the [MultiGov Architecture](/docs/learn/governance/architecture/){target=\_blank} page. - - -![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/learn/governance/multigov-high-level.webp) diff --git a/learn/index.md b/learn/index.md deleted file mode 100644 index 1f89c3859..000000000 --- a/learn/index.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Learn about Wormhole -description: Learn the basics of Wormhole, covering its architecture, messaging protocols, and how it enables multichain communication and asset transfers. -template: root-index-page.html ---- - -# Learn - -These informational sections will help you get to know Wormhole. Start with the fundamentals, then discover Wormhole's multichain transfer products and governance system. - -## Fundamentals - -To understand Wormhole from the ground up, visit the following sections. - -
- -- :octicons-book-16:{ .lg .middle } **Introduction to Wormhole** - - --- - - Learn more about the problems Wormhole solves, explore use cases, and view a list of supported blockchains. - - [:custom-arrow: Introduction to Wormhole](/docs/learn/introduction/) - -- :octicons-book-16:{ .lg .middle } **Messaging Infrastructure** - - --- - - Investigate the messaging protocol architecture with an in-depth exploration of the individual components powering Wormhole's infrastructure. - - [:custom-arrow: Understand Wormhole's infrastructure](/docs/learn/infrastructure/) - -
- -## Multichain Transfers - -Wormhole transfer products offer multiple options to meet your project's needs. Which product is best for your use depends upon the asset transfer type you want to add to your dApp. - -### Wrapped Tokens - -This method is likely familiar to you if you've previously built bridging projects. - -
- -- :octicons-book-16:{ .lg .middle } **Token Bridge** - - --- - - - Use Wormhole deployed contracts to simplify development - - Multichain token transfers through lock-and-mint-mechanism - - Option to include message payload for uses like social platforms - - [:custom-arrow: Learn about Token Bridge](/docs/learn/transfers/token-bridge/) - -
- -### Native Tokens - -Eliminate wrapped assets to preserve your token's native properties across chains. - -
- -- :octicons-book-16:{ .lg .middle } **Native Token Transfers** - - --- - - - Deploy custom smart contracts to retain token ownership and upgrade authority with complete customizability - - No wrapped tokens or liquidity pools to avoid slippage and MEV risk - - Custom attestation is available by adding external verifiers - - [:custom-arrow: Learn about Native Token Transfers](/docs/learn/transfers/native-token-transfers/) - -
- -### Intent-Based Transfers - -Institutional-scale digital asset settlement for individual users and insitutions. - -
- -- :octicons-book-16:{ .lg .middle } **Settlement** - - --- - - - Leverages three protocols, providing flexibility and redundancy - - Chain-agnostic to liquidity on chains, enabling broader chain support - - English auction determines the winning solver for settlement - - USDC as the shuttle asset for seamless cross-chain settlement - - [:custom-arrow: Learn about Settlement](/docs/learn/transfers/settlement/) - -
- -## Governance - -Explore MultiGov, Wormhole's multichain governance solution. - -
- -- :octicons-book-16:{ .lg .middle } **Multichain Governance** - - --- - - - Multichain voting and proposal execution - - Aggregates votes from all chains - - Can integrate with any Wormhole-supported blockchain - - [:custom-arrow: Learn about MultiGov](/docs/learn/governance/) - -
- -## Additional Resources - -
- -- :octicons-book-16:{ .lg .middle } **Product Comparison** - - --- - - Compare Wormhole's multichain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. - - [:custom-arrow: Compare Products](/docs/build/start-building/products/){target=\_blank} - -- :octicons-book-16:{ .lg .middle } **Use Cases** - - --- - - Explore Wormhole's use cases, from multichain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. - - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) - -
\ No newline at end of file diff --git a/learn/infrastructure/.pages b/learn/infrastructure/.pages deleted file mode 100644 index 636098c56..000000000 --- a/learn/infrastructure/.pages +++ /dev/null @@ -1,9 +0,0 @@ -title: Messaging Infrastructure -nav: - - index.md - - 'Architecture Overview': 'architecture.md' - - 'Core Contracts': 'core-contracts.md' - - 'VAAs': 'vaas.md' - - 'Guardians': 'guardians.md' - - 'Spy': 'spy.md' - - 'Relayers': 'relayer.md' diff --git a/learn/infrastructure/index.md b/learn/infrastructure/index.md deleted file mode 100644 index 87bd03148..000000000 --- a/learn/infrastructure/index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics ---- - -# Infrastructure Components - -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. - -## Get Started - -Start here for an overview of Wormhole architecture components and security mechanisms: - -
- -- :octicons-book-16:{ .lg .middle } **Architecture Overview** - - --- - - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. - - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) - -- :octicons-book-16:{ .lg .middle } **Security** - - --- - - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. - - [:custom-arrow: Learn About Security](/docs/learn/security/) - -
- -## Explore Components - -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: - -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] - -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. - -## Next Steps - -
- -- :octicons-book-16:{ .lg .middle } **Messaging Components** - - --- - - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) - -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** - - --- - - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. - - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) - -
diff --git a/learn/transfers/.pages b/learn/transfers/.pages deleted file mode 100644 index 70d592ca8..000000000 --- a/learn/transfers/.pages +++ /dev/null @@ -1,7 +0,0 @@ -title: Multichain Transfers -nav: - - index.md - - native-token-transfers - - settlement - - 'Token Bridge': 'token-bridge.md' - - 'CCTP Bridge': 'cctp.md' diff --git a/learn/transfers/cctp.md b/learn/transfers/cctp.md deleted file mode 100644 index 865bdbed8..000000000 --- a/learn/transfers/cctp.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Circle's CCTP Bridge -description: Unlock fast USDC transfers with Wormhole's integration of Circle's CCTP, featuring automatic relaying via the Wormhole relayer and native gas solutions. -categories: Transfer ---- - -# Circle's CCTP Bridge - -Wormhole Connect and the Wormhole TypeScript SDK support fast, cheap, native USDC bridging between all networks supported by Circle's [Cross-Chain Transfer Protocol](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. CCTP is Circle's native USDC cross-chain transfer attestation service. - -While this protocol is wholly separate from Wormhole itself, Wormhole builds on top of CCTP and adds several valuable augmentations, making it more straightforward to use and more useful for end users. These features include: - -- **Automated relaying** - eliminates the need for users to redeem USDC transfers themselves -- **Gas payment on the destination chain** - allows users to transfer USDC without needing to pay gas on the destination chain -- **Gas drop off** - enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer - -!!! note - Wormhole supports all CCTP-supported chains but at the moment only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank} are supported by Circle. - -You can use Wormhole's CCTP-powered USDC bridging by embedding the [Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or by integrating the [TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} directly. - -## Automatic Relaying - -To complete a CCTP transfer, the [Circle Attestation](https://developers.circle.com/api-reference/stablecoins/common/get-attestation){target=\_blank} must be delivered to the destination chain. - -This attestation delivery may be difficult or impossible in some contexts. For example, in a browser context, the user doesn't wish to wait for finality to deliver the attestation. To address this difficulty, the Wormhole CCTP relayer may be used either with the [Wormhole Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or more directly with the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank}. - -The Wormhole CCTP Relayer charges a fee to deliver the attestation and complete the transfer. - -| Chain | Fee | -|:---------------:|:---------------:| -| Ethereum | 1.0 USDC | -| Everything else | 0.1 USDC | - - - -## Native Gas Drop Off - -Another advantage of using the automatic relaying feature is the opportunity to transfer some native gas to the receiver on the destination chain. This feature is referred to as _native gas drop off_. - -The ability to perform native gas drop off addresses the common issue where a user may hold a balance of USDC but has no native gas to perform subsequent transactions. - - \ No newline at end of file diff --git a/learn/transfers/index.md b/learn/transfers/index.md deleted file mode 100644 index bdd546a2c..000000000 --- a/learn/transfers/index.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Multichain Transfers -description: This section introduces the core messaging protocols that power seamless multichain communication and asset transfer within the Wormhole ecosystem. -categories: Transfer ---- - -# Multichain Transfers - -These sections include information about Wormhole's transfer products to help you learn how they work and determine the best transfer product to fit your needs. - -Use the following links to jump directly to each Wormhole transfer product information page or continue for a product comparison: - -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/) - a mechanism to transfer native tokens multichain seamlessly without converting to a wrapped asset -- [**Settlement**](/docs/learn/transfers/settlement/) - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -- [**Token Bridge**](/docs/learn/transfers/token-bridge/) - a bridging solution that uses a lock and mint mechanism - -## Compare Transfer Products - -A few key comparisons can help you readily differentiate between Wormhole transfer product offerings. Use the following sections to help compare and select products: - -### NTT vs. Token Bridge - -Understand the key differences between Native Token Transfers (NTT) and Token Bridge to determine which solution best fits your needs. - -- Native Token Transfers (NTT) move tokens in their original form without wrapping them, ensuring compatibility with on-chain applications but requiring custom contracts on both the source and destination chains -- Token Bridge locks tokens on the source chain and mints wrapped versions on the destination chain. This method does not require changes to existing token contracts and supports additional message payloads for more complex use cases - -
- -| Supports | NTT | Token Bridge | -|---------------------------|--------------------|--------------------| -| Message Payload | :white_check_mark: | :white_check_mark: | -| Wrapped Assets | :x: | :white_check_mark: | -| Native Assets | :white_check_mark: | :x: | -| Contract-Free Development | :x: | :white_check_mark: | -| User-Owned Contracts | :white_check_mark: | :x: | - -
- -In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - -
- - -### Settlement - -Settlement enables fast and efficient multichain transfers by optimizing liquidity without relying on traditional bridging methods. Unlike NTT, which moves native assets directly between chains, and Token Bridge, which locks tokens and mints wrapped versions, Settlement uses intent-based execution. Users specify the desired transfer outcome, and solvers compete to fulfill it most efficiently. - -By leveraging a decentralized solver network, Settlement ensures efficient cross-chain liquidity without locking assets or requiring asset wrapping, providing a seamless and capital-efficient solution for multichain transactions. - -## Additional Resources - -
- -- :octicons-tools-16:{ .lg .middle } **Product Comparison** - - --- - - Compare Wormhole's multichain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. - - [:custom-arrow: Compare Products](/docs/build/start-building/products/#transfer-products) - -- :octicons-book-16:{ .lg .middle } **Use Cases** - - --- - - Explore Wormhole's use cases, from multichain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. - - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) - - -
diff --git a/learn/transfers/native-token-transfers/.pages b/learn/transfers/native-token-transfers/.pages deleted file mode 100644 index ab69536d2..000000000 --- a/learn/transfers/native-token-transfers/.pages +++ /dev/null @@ -1,7 +0,0 @@ -title: Native Token Transfers -nav: - - index.md - - 'Overview': 'overview.md' - - 'Architecture': 'architecture.md' - - 'Deployment Models': 'deployment.md' - - 'Security': 'security.md' \ No newline at end of file diff --git a/learn/transfers/native-token-transfers/deployment.md b/learn/transfers/native-token-transfers/deployment.md deleted file mode 100644 index 27cd320a8..000000000 --- a/learn/transfers/native-token-transfers/deployment.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Native Token Transfers - Deployment Models -description: Explore Wormhole's Native Token Transfers deployment models——hub-and-spoke, burn-and-mint——for seamless cross-chain token transfers. -categories: NTT, Transfer ---- - -# Deployment Models - -The Wormhole framework offers two deployment models, each catering to different token management needs: the hub-and-spoke model and the burn-and-mint model. These models provide flexible solutions for both existing token deployments and new projects looking to enable secure and seamless multichain token transfers. - -## Hub-and-Spoke - -The hub-and-spoke model involves locking tokens on a central hub chain and minting them on destination spoke chains. This model maintains the total supply on the hub chain and is backward-compatible with any existing token deployment. - -This model is ideal for existing token deployments that don't want to alter existing token contracts. It maintains the canonical balance on a hub chain while allowing for secure native deployment to new blockchains. - -- **Hub chain** - tokens are locked when initiating a transfer -- **Spoke chains** - Equivalent tokens are minted on the destination chain - -When transferring tokens back to the original hub chain, the tokens on the source spoke chain are burned, and the previously locked tokens on the hub chain are unlocked. However, when transferring tokens directly between spoke chains, the tokens are burned on the source spoke chain and minted on the destination spoke chain. - -## Burn-and-Mint - -The burn-and-mint model involves burning tokens on the source chain and minting them on the destination chain. This results in a simplified multichain transfer process that distributes the total supply across multiple chains and produces a native multichain token. - -This model best suits new token deployments or projects willing to upgrade existing contracts. - -- **Source chain** - tokens are burned when initiating a transfer -- **Destination chain** - equivalent tokens are minted on the destination chain \ No newline at end of file diff --git a/learn/transfers/native-token-transfers/index.md b/learn/transfers/native-token-transfers/index.md deleted file mode 100644 index 0ad1e756d..000000000 --- a/learn/transfers/native-token-transfers/index.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: A Quick Look at Native Token Transfers -description: This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- - -# Native Token Transfers - -## Get Started - -This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. - -
- -- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Dive into an introduction to NTT and discover what NTT is, what its key features are, and the available integration paths. - - [:custom-arrow: Learn more about NTT](/docs/learn/transfers/native-token-transfers/overview/) - -- :octicons-question-16:{ .lg .middle } **Architecture** - - --- - - Explore NTT's architecture to understand its core components and how they work together to manage cross-chain communication. - - [:custom-arrow: Discover how NTT works](/docs/learn/transfers/native-token-transfers/architecture/) - -- :octicons-book-16:{ .lg .middle } **Deployment Models** - - --- - - The NTT framework offers two deployment models for different token management needs: the hub-and-spoke and burn-and-mint models. - - [:custom-arrow: Check out the deployment models](/docs/learn/transfers/native-token-transfers/deployment/) - -- :octicons-shield-lock-16:{ .lg .middle } **Security** - - --- - - Explore NTT's security measures, including the Global Accountant and governance strategies for seamless token safety. - - [:custom-arrow: Review the security measures](/docs/learn/transfers/native-token-transfers/security/) - -
- -## Next Steps - -Ready to dive in and start building? Check out the following resources to begin the deployment process and make the most of your deployment. - -
- -- :octicons-rocket-16:{ .lg .middle } **Deploy NTT** - - --- - - Explore detailed guides that walk you through the entire deployment process, from installing the NTT CLI to deploying NTT across supported chains. - - [:custom-arrow: Deploy now using the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/) - -- :octicons-checklist-16:{ .lg .middle } **Post Deployment Recommendations** - - --- - - Already deployed your NTT project? Check out these post deployment recommendations and integration demos to get the most out of your deployment. - - [:custom-arrow: Get the most of out your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) - -
diff --git a/learn/transfers/native-token-transfers/overview.md b/learn/transfers/native-token-transfers/overview.md deleted file mode 100644 index 2107377ae..000000000 --- a/learn/transfers/native-token-transfers/overview.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Native Token Transfers Overview -description: Explore Wormhole's Native Token Transfers for flexible cross-chain transfers with full control over token behavior, security, and integration features. -categories: NTT, Transfer ---- - -# Native Token Transfers - -!!!tip "Looking to deploy NTT?" - If you're ready to deploy NTT or access the CLI, follow the detailed [NTT Deployment Section](/docs/build/transfers/native-token-transfers/deployment-process/){target=\_blank}. - - - For deployment steps on EVM, visit the [Deploy to EVM page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} - - For deployment steps on Solana, visit the [Deploy to Solana page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/){target=\_blank} - -## Introduction - -Wormhole's Native Token Transfers (NTT) is an open source, flexible, and composable framework for transferring tokens across blockchains. By eliminating wrapped assets, NTT preserves each token’s native properties across chains, letting you maintain complete control over metadata, ownership, upgrade authority, and other custom features. - -The framework offers two modes of operation for existing token deployments. In locking mode, the original token supply is preserved on a single chain. In contrast, the burning mode enables the deployment of multichain tokens, distributing the supply across various chains. - -## Key Features - -Wormhole's Native Token Transfers (NTT) framework offers a comprehensive and flexible solution for seamless token transfers across blockchains. Below are some of the key features that make this framework stand out: - -- **No wrapped tokens** – tokens remain native on every chain where NTT is deployed. All token properties and metadata remain consistent, avoiding any confusion or overhead introduced by wrapped tokens -- **Unified user experience** - tokens retain their properties on each chain, remaining completely fungible and ensuring a consistent user experience -- **No liquidity pools** - transfer tokens without the need for liquidity pools, avoiding fees, slippage, and MEV risk -- **Integrator flexibility** - retained ownership, upgrade authority, and complete customizability over token contracts -- **Advanced rate limiting** - inbound and outbound rate limits are configurable per chain and over arbitrary periods, preventing abuse while managing network congestion and allowing for controlled deployments to new chains -- **Global Accountant** - ensures accounting integrity across chains by checking that the number of tokens burned and transferred out of a chain never exceeds the number of tokens minted -- **Access control** - to prevent unauthorized calls to administrative functions, protocols can choose to assign specific functions, such as the Pauser role, to a separate address from the owner -- **Maximum composability** - open source and extensible for widespread adoption and integration with other protocols -- **Custom attestation** - optionally add external verifiers and configure custom message attestation thresholds - -## Integration Paths - -Integrators looking to deploy their token to connected chains can use the NTT framework or the Token Bridge. Both options carry a distinct integration path and feature set depending on your requirements, as outlined in the following sections. - -### Native Token Transfers Framework - -The Native Token Transfers Framework is highly customizable and ideal for applications such as a DeFi governance token deployed across multiple chains, which seeks to achieve fungible multichain liquidity and direct integration into governance processes. - -- **Mechanism** - can entirely utilize a burn-and-mint mechanism or can be paired for a hub-and-spoke model -- **Security** - fully configurable rate limiting, pausing, access control, and threshold attestations. Integrated with the Global Accountant -- **Contract ownership** - retain ownership and upgrade authority of token contracts on each chain -- **Token contracts** - native contracts owned by your protocol governance -- **Integration** - streamlined, customizable framework allows for more sophisticated and bespoke deployments - -The following example projects demonstrate the use of the Wormhole NTT framework through Wormhole Connect and the TypeScript SDK: - -- [NTT Connect](https://github.com/wormhole-foundation/demo-ntt-connect){target=\_blank} -- [NTT TS SDK](https://github.com/wormhole-foundation/demo-ntt-ts-sdk){target=\_blank} - -### Token Bridge - -The Token Bridge offers a secure, low-effort integration suitable for applications like a Web3 game that wants to make its token tradable across multiple chains. - -- **Mechanism** - solely utilizes a lock and mint model. Unlike NTT, the Token Bridge issues a wrapped asset on the destination chain, rather than preserving the original token contract -- **Security** - preconfigured rate limiting and integrated Global Accountant -- **Contract ownership** - Token Bridge contracts are upgradeable via [Wormhole Governance](/docs/learn/security/){target=\_blank} -- **Token contracts** - wrapped asset contract owned by the Wormhole Token Bridge contract, upgradeable via a 13/19 Guardian governance process -- **Integration** - straightforward and permissionless method to deploy on multiple chains - -!!! note - [Learn more](/docs/learn/infrastructure/vaas/){target=\_blank} about the core messaging primitives in the Wormhole network. - -## Supported Token Standards - -Native Token Transfers (NTT) in Wormhole primarily support **ERC-20 tokens**, the most widely used standard for fungible tokens on the Ethereum network and other EVM-compatible blockchains. The NttManager contract leverages the IERC20 interface and SafeERC20 utility from OpenZeppelin to ensure secure and efficient token transfers. Additionally, it supports ERC-20 Burnable tokens, allowing tokens to be burned on the source chain when needed for cross-chain transfers. At this time, NTT focuses on ERC-20 tokens, and other token standards, such as ERC-721 (non-fungible tokens) or ERC-1155 (multi-token standard), are not natively supported. \ No newline at end of file diff --git a/learn/transfers/settlement/.pages b/learn/transfers/settlement/.pages deleted file mode 100644 index e9329c638..000000000 --- a/learn/transfers/settlement/.pages +++ /dev/null @@ -1,5 +0,0 @@ -title: Settlement -nav: - - index.md - - 'Overview': 'overview.md' - - 'Protocol Architectures': 'architecture.md' \ No newline at end of file diff --git a/learn/transfers/settlement/index.md b/learn/transfers/settlement/index.md deleted file mode 100644 index d1e7a166c..000000000 --- a/learn/transfers/settlement/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Wormhole Settlement -description: Learn about Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. -categories: Settlement, Transfer ---- - -# Wormhole Settlement - -## Get Started - -This section covers Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. - -
- -- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. - - [:custom-arrow: Learn more about Wormhole Settlement](/docs/learn/transfers/settlement/overview/) - -- :octicons-question-16:{ .lg .middle } **Protocol Architectures** - - --- - - Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP — for scalable, efficient cross-chain asset transfers. - - [:custom-arrow: Discover protocol architectures](/docs/learn/transfers/settlement/architecture/) - -
\ No newline at end of file diff --git a/learn/transfers/settlement/overview.md b/learn/transfers/settlement/overview.md deleted file mode 100644 index c3e3614a8..000000000 --- a/learn/transfers/settlement/overview.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Wormhole Settlement Overview -description: Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. -categories: Settlement, Transfer ---- - -# Wormhole Settlement Overview - -## Introduction - -Wormhole Settlement is a fast, institutional-scale digital asset settlement — a new way to transfer assets across chains. - -With Wormhole Settlement, an intent-based asset transfer for individual users and institutions, you can swap, bridge, and build across multiple chains. You can implement cross-chain functionality within your dApps extremely simply and without compromising user experience, widening the horizons of your product offerings and the number and type of users you can cater to. - -The Settlement supports Ethereum, Ton, Optimism, Arbitrum, Base, Avalanche, Unichain, Polygon, Solana, and Sui, with many more on the horizon. It is powered by Wormhole Messaging, Wormhole Native Token Transfer (NTT), and Circle's CCTP and built in collaboration with the intent experts at Mayan Finance. - -Settlement represents Wormhole's first step towards optimizing the bridging experience and building a product that users and institutions use daily. Use it to send assets between chains, rebalance institutional inventories on-chain cheaply and quickly, or allow your application to be accessible by any user no matter what assets they hold or what chain they call home. - -## Key Features - -- **Integrator flexibility** - apps leveraging the SDK can select any one of three potential routes surfaced, each with its tradeoffs concerning time vs cost; they may extend this to users as well -- **Scalable liquidity** - taking into account the sometimes idiosyncratic yet sharp inflows into the Solana ecosystem, the hub-spoke model of the Wormhole Liquidity Layer and the flexible design of Swift are designed for capital efficiency -- **Arbitrary payload support** - integrators can bundle `callData` containing arbitrary protocol actions to enable seamless one-click user experiences, such as swap plus stake - -## Integrator Paths - -### SDK Integrators - -Wormhole provides an SDK that enables apps to abstract away the complexity of cross-chain token swaps. The SDK handles route discovery, fee estimation, and transaction construction. Apps can embed this feature in their backend or create an interface for users to bridge into their respective ecosystems quickly. - -### NTT Integrators - -NTT partners, current and future, can leverage Wormhole Settlement for near-instant NTT transfers from any chain, including Ethereum mainnet and its L2s. This eliminates waiting for slow source chain confirmation times (sometimes 15 minutes or more). If interested, please [fill out this interest form](https://wormhole.com/contact){target=\_blank}. - -### Chain Integrators - -Due to the hub-spoke model of liquidity, new chains without proven traction can access the same level of liquidity for cross-chain intent fulfillment from day one of mainnet launch as established ecosystems with clear evidence of adoption. - -!!!tip - Looking to integrate Wormhole Settlement? If you're ready, check out how to [integrate Wormhole Settlement Routes using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank}. - -## Related Resources - -- To learn more about the architecture of Wormhole-native swap protocols, see the [Settlement Protocol Architectures](/docs/learn/transfers/settlement/architecture/){target=\_blank} page \ No newline at end of file diff --git a/learn/transfers/token-bridge.md b/learn/transfers/token-bridge.md deleted file mode 100644 index 31be693b5..000000000 --- a/learn/transfers/token-bridge.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Token Bridge -description: Learn about Wormhole's Token Bridge for cross-chain transfers using lock and mint mechanisms, ensuring secure and efficient asset movement. -categories: Token-Bridge, Transfer ---- - -# Token Bridge - -Transferring tokens across blockchain networks is challenging due to the lack of interoperability. Maintaining token properties such as value, name, and precision while ensuring security during transfers often requires complex and costly solutions like liquidity pools or native swaps, which can introduce inefficiencies and risks. - -Wormhole’s Token Bridge addresses these challenges by providing a decentralized protocol for seamless cross-chain token transfers through a lock-and-mint mechanism. Using Wormhole’s message-passing protocol, the Token Bridge allows standards-compliant tokens, like ERC-20 on Ethereum or SPL on Solana, to be transferred between different blockchains while preserving their original attributes. - -Offering a more efficient, scalable, and secure alternative to traditional solutions, the Token Bridge ensures that assets retain their properties across multiple blockchain ecosystems. Additionally, it supports flexible features like [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, enabling custom interactions by allowing tokens to carry additional data for smart contract integration on the destination chain. - -This page introduces the core concepts and functions of Wormhole’s Token Bridge, explaining how it operates, its key features, and how it enables secure and efficient cross-chain token transfers. - -### How Does It Work? - -At the core of the Token Bridge lies the lock-and-mint mechanism, which uses the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} with a specific [payload](/docs/learn/infrastructure/vaas/#token-transfer){target=\_blank} to pass information about the transfer. Tokens on the source chain are locked, and wrapped tokens are minted on the destination chain. This approach guarantees that token transfers are secure and consistent, ensuring that token properties such as name, symbol, and decimal precision are preserved across chains. - -Before a token can be transferred to a new chain, the token’s metadata must be [attested](/docs/learn/infrastructure/vaas/#attestation){target=\_blank}. This process registers the token details (such as decimals and symbol) on the destination chain, enabling the creation of wrapped assets. - -While the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} has no specific receiver by default, transfers sent through the Token Bridge do have a specific receiver chain and address to ensure the tokens are minted to the expected recipient. - -In addition to standard token transfers, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}. This functionality allows users to attach additional data to token transfers, enabling more complex interactions with smart contracts on the destination chain. For instance, a token transfer can include a payload that triggers specific actions, such as interacting with a decentralized exchange (DEX) or automated market maker (AMM). - -### Token Transfer Flow - -The transfer process is simple yet secure, involving a few key steps: - -1. **Attestation** - first, a token's metadata is attested on the source chain, ensuring that its properties are consistent across chains -2. **Locking** - on the source chain, the native token is locked in a custody account -3. **Message emission** - a message detailing the transfer is sent through Wormhole’s Guardian Network, which verifies the transfer and signs the message -4. **Verification and minting** - on the destination chain, the transfer message is verified, and wrapped tokens are minted, or native tokens are released from custody - -![Token Bridge detailed flow](/docs/images/learn/transfers/token-bridge/token-bridge-diagram.webp) - -### Key Features of the Token Bridge - -The Token Bridge creates wrapped versions when tokens are transferred to a different chain. These wrapped assets represent the locked tokens on the source chain and allow users to interact with them on the destination chain. This mechanism ensures seamless functionality without needing liquidity pools or native token swaps. - -The Token Bridge employs a universal token representation that is compatible with various virtual machine (VM) data types. This allows the tokens to interact with decentralized applications (dApps) across different chains without issues related to differing token standards. - -### Message and Payload Structure - -To facilitate cross-chain communication, the Token Bridge uses specialized payloads that carry the necessary information for token transfers and attestations. These payloads ensure that the correct tokens are minted or unlocked on the destination chain. - -- `Transfer` - this payload initiates the transfer of tokens, either by minting wrapped tokens or releasing locked tokens -- `TransferWithPayload` - in addition to transferring tokens, this payload carries additional data, allowing integration with smart contracts or dApps on the target chain -- `AssetMeta` - before a token can be transferred for the first time, this payload is used to attest to the token’s metadata, including decimals, symbol, and name -- `RegisterChain` - register the Token Bridge contract (emitter address) for a foreign chain -- `UpgradeContract` - upgrade the contract - -Each payload type is designed to serve a specific function in the token transfer process, ensuring that the bridge operates efficiently and securely. - -One of the key challenges in cross-chain token transfers is maintaining the correct token precision. The Token Bridge addresses this using the `AssetMeta` payload to store token metadata. Before transferring a token to a new chain, metadata such as its decimal precision, name, and symbol must be attested. The bridge ensures token amounts are truncated to a maximum of 8 decimals, guaranteeing compatibility with chains that may not support higher decimal precision. For example, an 18-decimal token on Ethereum will be represented with only eight decimals on the destination chain, simplifying integration with various decentralized applications. - -### Security and Authorization - -The Token Bridge uses an emitter chain and address authorization system to verify the validity of messages. Each Token Bridge endpoint is registered on its respective chain, ensuring only trusted contracts can send or receive transfer messages. - -The [Wormhole Guardian Network](/docs/learn/infrastructure/guardians/#guardian-network){target=\_blank} plays a critical role in verifying each transfer and ensuring that the message is signed and relayed securely between chains. - -### Portal Bridge - -A real-world example of Wormhole's Token Bridge in action is the [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides users with a simple interface to transfer tokens across multiple blockchains. Using the Wormhole infrastructure, Portal Bridge guarantees secure and seamless cross-chain transfers, making it easier for users to move assets between different blockchain ecosystems. diff --git a/llms-files/llms-basics.txt b/llms-files/llms-basics.txt index 852a7e35e..443733747 100644 --- a/llms-files/llms-basics.txt +++ b/llms-files/llms-basics.txt @@ -6,2028 +6,2486 @@ It is intended for use with large language models (LLMs) to support developers w This file includes documentation related to the category: Basics ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/glossary.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/core-contracts.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/guardians.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/relayer.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/spy.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/vaas.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/introduction.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/security.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/core-contracts.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/wormhole-relayers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/products.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/use-cases.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/core-contracts.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/wormhole-relayers.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/products.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/glossary.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/ecosystem.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/core-contracts.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/guardians.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/relayer.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/spy.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/vaas.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/introduction.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/security.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/get-started.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary - -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +# Get Started with Messaging -## Chain ID +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +## Prerequisites -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +Before you begin, ensure you have the following: -## Consistency Level +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +## Configure Your Messaging Environment -## Delivery Provider +1. Create a directory and initialize a Node.js project: -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -## Emitter +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -## Finality +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + ```bash + npx tsc --init + ``` -## Guardian + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Guardian Network + ```bash + npm install @wormhole-foundation/sdk + ``` -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. Create a new file named `main.ts`: -## Guardian Set + ```bash + touch main.ts + ``` -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Heartbeat + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -## Observation + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -## Relayer + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -A relayer is any process that delivers VAAs to a destination. +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -## Sequence + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +2. Run the script using the following command: -## Spy + ```bash + npx tsx main.ts + ``` -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-## VAA +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -## Validator +## Next Steps -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Infrastructure Components - -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. - -## Get Started +# Get Started with Core Contracts -Start here for an overview of Wormhole architecture components and security mechanisms: +## Introduction -
+Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - --- +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +## Prerequisites - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +To interact with the Wormhole Core Contract, you'll need the following: -- :octicons-book-16:{ .lg .middle } **Security** +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - --- +## How to Interact with Core Contracts - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - [:custom-arrow: Learn About Security](/docs/learn/security/) +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -
+While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -## Explore Components +### Sending Messages -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +=== "EVM" -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -## Next Steps + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -
+ ??? interface "Parameters" -- :octicons-book-16:{ .lg .middle } **Messaging Components** + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. - --- + --- - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - --- + ??? interface "Returns" - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -
---- END CONTENT --- +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- +// Check fee and send parameters -# Architecture +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -## Overview +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +=== "Solana" -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + ??? interface "Parameters" -## On-Chain Components + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -## Off-Chain Components + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -## Next Steps + ??? child "Type `PostMessage<'info>`" -
+ ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -- :octicons-book-16:{ .lg .middle } **Core Contracts** + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - --- + --- - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + `batch_id` ++"u32"++ + + An identifier for the message batch. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. - --- + --- - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -
---- END CONTENT --- + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -# Core Contracts +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -## Introduction - -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. - -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. - -## Key Functions - -Key functions of the Wormhole Core Contract include the following: - -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -## How the Core Contract Works + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The following describes the role of the Wormhole Core Contract in message transfers: +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions +### Receiving Messages -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. +The way a message is received and handled depends on the environment. -### Message Submission +=== "EVM" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + ??? interface "Parameters" -### Message Reception + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + ??? interface "Returns" -## Multicast + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + ??? child "Struct `VM`" -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -## Next Steps + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -
+ ??? interface "Example" -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); - --- + // Perform safety checks here - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + // Your custom application logic here +} + ``` -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - --- +=== "Solana" - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + Retrieve the raw message data: -
---- END CONTENT --- + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Example" -## Guardian + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -Guardians fulfill their role in the messaging protocol as follows: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +#### Validating the Emitter -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -## Guardian Network +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -The Guardian Network is designed to help Wormhole deliver on five key principles: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -The following sections explore each principle in detail. +await tx.wait(); +``` -### Decentralization +#### Additional Checks -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Two common approaches to decentralization have notable limitations: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +## Source Code References -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -To answer that, consider these key constraints and design decisions: +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +# Wormhole Relayer -### Modularity +## Introduction -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -### Chain Agnosticism +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +## Get Started with the Wormhole Relayer -### Scalability +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +### Wormhole Relayer Interfaces -### Upgradeable +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -Wormhole is designed to adapt and evolve in the following ways: +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +## Interact with the Wormhole Relayer -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -## Next Steps +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -
+To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -- :octicons-book-16:{ .lg .middle } **Relayers** +Your initial set up should resemble the following: - --- +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +contract Example { + IWormholeRelayer public wormholeRelayer; -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` - --- +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +### Send a Message - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -
---- END CONTENT --- +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -# Relayers +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -There are three primary types of relayers discussed: +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +### Receive a Message -## Fundamentals +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Key characteristics of VAAs include: +## Delivery Guarantees -- Public emission from the Guardian Network +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- Authentication through signatures from the Guardian Network +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- Verifiability by any entity or any Wormhole Core Contract +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +## Delivery Statuses -Keep in mind the following security considerations around relayers: +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -## Client-Side Relaying +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -### Key Features +## Other Considerations -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -### Implementation +## Track the Progress of Messages with the Wormhole CLI -Users themselves carry out the three steps of the cross-chain process: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -1. Perform an action on chain A +=== "Mainnet" -2. Retrieve the resulting VAA from the Guardian Network + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -3. Perform an action on chain B using the VAA +=== "Testnet" -### Considerations + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -- Users must sign all required transactions with their own wallet +## Step-by-Step Tutorial -- Users must have funds to pay the transaction fees on every chain involved +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -- The user experience may be cumbersome due to the manual steps involved +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -## Custom Relayers +# Messaging Overview -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +## Key Features -### Key Features +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## How It Works -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +The messaging flow consists of several core components: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -### Implementation +## Use Cases -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Considerations +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- Development work and hosting of relayers are required +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +- **Gas Abstraction** -## Wormhole Relayers + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +- **Bridging Intent Library** -### Key Features + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -### Implementation +## Next Steps -The Wormhole relayer integration involves two key steps: +Follow these steps to work with Wormhole Messaging: -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Considerations +# Products -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- All computations are performed on-chain +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -- Potentially less gas-efficient compared to custom relayers +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +## Transfer Products -- Support may not be available for all chains +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -## Next Steps +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-- :octicons-book-16:{ .lg .middle } **Spy** +::spantable:: - --- +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +::end-spantable:: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +
-- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - --- +
- Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +## Bridging UI -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - --- +## Real-time Data - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Multichain Governance -
+[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Spy +# Glossary -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Chain ID -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -## Key Features +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +## Consistency Level -## Integrator Use Case +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +## Delivery Provider -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -## Observable Message Categories +## Emitter -A Spy can access the following categories of messages shared over the gossip protocol: +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +## Finality - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network - - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events - -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status - - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network - -## Additional Resources - -
- -- :octicons-code-16:{ .lg .middle } **Spy Source Code** - - --- - - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +## Guardian -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - --- +## Guardian Network - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +## Guardian Set -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - --- +## Heartbeat - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -
+## Observation -## Next Steps +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -
+## Relayer -- :octicons-code-16:{ .lg .middle } **Run a Spy** +A relayer is any process that delivers VAAs to a destination. - --- +## Sequence - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +## Spy -- :octicons-code-16:{ .lg .middle } **Use Queries** +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - --- +## VAA - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +## Validator -
+A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/protocol/architecture/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Architecture -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Overview -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -## VAA Format +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -The basic VAA consists of header and body components described as follows: +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - Where each `signature` is: + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## On-Chain Components -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +## Off-Chain Components -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Consistency and Finality +## Next Steps -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +
-Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- :octicons-book-16:{ .lg .middle } **Core Contracts** -## Signatures + --- -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -## Payload Types + --- -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -### Token Transfer + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +
+--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# The Wormhole Ecosystem -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Ecosystem Overview -### Attestation +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -The message format for token attestation is as follows: +## Bringing It All Together: Interoperability in Action -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. -#### Attestation Tips +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -Be aware of the following considerations when working with attestations: +## Next Steps -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +# Core Contracts -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Introduction -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer with Message +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +## Key Functions -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Key functions of the Wormhole Core Contract include the following: -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## How the Core Contract Works -### Governance +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +The following describes the role of the Wormhole Core Contract in message transfers: -#### Action Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Message Submission -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -#### Actions +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +### Message Reception -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Lifetime of a Message +## Multicast -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Introduction to Wormhole +## Guardian -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Guardians fulfill their role in the messaging protocol as follows: -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +## Guardian Network -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +The Guardian Network is designed to help Wormhole deliver on five key principles: -## What Problems Does Wormhole Solve? +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following sections explore each principle in detail. -Critical problems Wormhole addresses include: +### Decentralization -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -## What Does Wormhole Offer? +Two common approaches to decentralization have notable limitations: -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -## What Isn't Wormhole? +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +To answer that, consider these key constraints and design decisions: -## Use Cases of Wormhole +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -Consider the following examples of potential applications enabled by Wormhole: +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +### Modularity -## Explore +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -Discover more about the Wormhole ecosystem, components, and protocols: +### Chain Agnosticism -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -## Demos +### Scalability -Demos offer more realistic implementations than tutorials: +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. - +### Upgradeable -!!! note - Wormhole Integration Complete? +Wormhole is designed to adapt and evolve in the following ways: - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + +## Next Steps -## Supported Blockchains +
+ +- :octicons-book-16:{ .lg .middle } **Relayers** + + --- + + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. + + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -Wormhole supports a growing number of blockchains. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + + --- + + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Security +# Relayers -## Core Security Assumptions +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +There are three primary types of relayers discussed: -In summary: +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -## Guardian Network +## Fundamentals -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -### Governance +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +Key characteristics of VAAs include: -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +- Public emission from the Guardian Network -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +- Authentication through signatures from the Guardian Network -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- Verifiability by any entity or any Wormhole Core Contract -Via governance, the Guardians can: +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +Keep in mind the following security considerations around relayers: -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## Monitoring +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +## Client-Side Relaying -Guardians monitor: +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Key Features -## Asset Layer Protections +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +### Implementation -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Users themselves carry out the three steps of the cross-chain process: -## Open Source +1. Perform an action on chain A -Wormhole builds in the open and is always open source. +2. Retrieve the resulting VAA from the Guardian Network -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +3. Perform an action on chain B using the VAA -## Audits +### Considerations -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +- Users must sign all required transactions with their own wallet -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +- Users must have funds to pay the transaction fees on every chain involved -## Bug Bounties +- The user experience may be cumbersome due to the manual steps involved -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +## Custom Relayers -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +### Key Features -## Learn More +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics ---- +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -# Get Started with Core Contracts +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience -## Introduction +### Implementation -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +### Considerations -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." -## Prerequisites +- Development work and hosting of relayers are required -To interact with the Wormhole Core Contract, you'll need the following: +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +- Relayers are responsible for availability, and adding dependencies for the cross-chain application -## How to Interact with Core Contracts +## Wormhole Relayers -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +### Key Features -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -### Sending Messages +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +### Implementation -=== "EVM" +The Wormhole relayer integration involves two key steps: - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ??? interface "Parameters" +### Considerations - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - --- +- All computations are performed on-chain - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +- Potentially less gas-efficient compared to custom relayers - --- +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- Support may not be available for all chains - ??? interface "Returns" +## Next Steps - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +
- ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +- :octicons-book-16:{ .lg .middle } **Spy** -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); - -// Check fee and send parameters - -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); - -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); - -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - -=== "Solana" - - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: - - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` - - ??? interface "Parameters" - - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" - - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. - - ??? child "Type `PostMessage<'info>`" - - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - - --- + --- - `batch_id` ++"u32"++ - - An identifier for the message batch. + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - --- + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - --- + --- - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters + --- -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +
+--- END CONTENT --- -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +# Spy -### Receiving Messages +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -The way a message is received and handled depends on the environment. +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. -=== "EVM" +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +## Key Features - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - ??? interface "Parameters" +## Integrator Use Case - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ??? interface "Returns" +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +## Observable Message Categories - ??? child "Struct `VM`" +A Spy can access the following categories of messages shared over the gossip protocol: - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events - ??? interface "Example" +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network - // Perform safety checks here +## Additional Resources - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +
- // Your custom application logic here -} - ``` +- :octicons-code-16:{ .lg .middle } **Spy Source Code** - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + --- -=== "Solana" + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} - Retrieve the raw message data: +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` + --- - ??? interface "Example" + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. + --- -#### Validating the Emitter + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: +
-```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +## Next Steps -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +
-```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +- :octicons-code-16:{ .lg .middle } **Run a Spy** -await tx.wait(); -``` + --- -#### Additional Checks + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- :octicons-code-16:{ .lg .middle } **Use Queries** -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + --- -## Source Code References + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ --- BEGIN CONTENT --- --- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics --- -# Wormhole Relayer - -## Introduction - -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. - -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +# Verified Action Approvals -## Get Started with the Wormhole Relayer +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -### Wormhole Relayer Interfaces +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +## VAA Format -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from +The basic VAA consists of header and body components described as follows: -## Interact with the Wormhole Relayer +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + Where each `signature` is: -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -Your initial set up should resemble the following: +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -contract Example { - IWormholeRelayer public wormholeRelayer; +## Consistency and Finality - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -### Send a Message +## Signatures -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) ``` -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +## Payload Types -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +### Token Transfer -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +Transferring tokens from the sending chain to the destination chain requires the following steps: -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -### Receive a Message +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -## Delivery Guarantees +### Attestation -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +The message format for token attestation is as follows: -## Delivery Statuses +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +#### Attestation Tips -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Be aware of the following considerations when working with attestations: -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -## Other Considerations +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +### Token Transfer with Message -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -## Track the Progress of Messages with the Wormhole CLI +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -=== "Mainnet" +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +### Governance -=== "Testnet" +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +#### Action Structure -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -## Step-by-Step Tutorial +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -# Products +#### Actions -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +## Lifetime of a Message -## Transfer Products +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -
+![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -::spantable:: +## Next Steps -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +
-::end-spantable:: +- :octicons-book-16:{ .lg .middle } **Guardians** -
+ --- -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -## Bridging UI + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -## Real-time Data + --- -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -## Multichain Governance + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ +Doc-Content: https://wormhole.com/docs/protocol/introduction/ --- BEGIN CONTENT --- --- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. categories: Basics --- -# Wormhole Use Cases +# Introduction to Wormhole -
-
+In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -## Cross-Chain Swaps and Liquidity Aggregation +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -Enable seamless swaps between chains with real-time liquidity routing. +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -
-
+![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -🛠 **Wormhole products used:** +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} +This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -
-
+## What Problems Does Wormhole Solve? +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -
-
+Critical problems Wormhole addresses include: -## Borrowing and Lending Across Chains +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -Let users borrow assets on one chain using collateral from another. +## What Does Wormhole Offer? -
-
+Wormhole provides a suite of tools and protocols that support a wide range of use cases: -🛠 **Wormhole products used:** +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +## What Isn't Wormhole? -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -
-
+## Use Cases of Wormhole +Consider the following examples of potential applications enabled by Wormhole: -
-
+- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -## Real-Time Price Feeds and Trading Strategies +## Explore -Fetch price feeds across multiple chains for DeFi applications. +Discover more about the Wormhole ecosystem, components, and protocols: -
-
+- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -🛠 **Wormhole products used:** +## Demos -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +Demos offer more realistic implementations than tutorials: -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -
-
+ -
-
+!!! note + Wormhole Integration Complete? -## Asset Movement Between Bitcoin and Other Chains + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -Enable direct BTC transfers without wrapped assets. + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -
-
+## Supported Networks by Product -🛠 **Wormhole products used:** +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +# Security -
-
+## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -## Decentralized Social Platforms +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -Enable seamless communication and asset transfer across decentralized social networks. +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -🛠 **Wormhole products used:** +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +## Guardian Network -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -
-
+### Governance +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -## Memecoin Launchpads +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: -🛠 **Wormhole products used:** +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +## Monitoring -
-
+A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: -## Cross-Chain Perpetuals +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +## Asset Layer Protections -
-
+One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -🛠 **Wormhole products used:** +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +## Open Source -
-
+Wormhole builds in the open and is always open source. +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -
-
+## Audits -## Gas Abstraction +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -
-
+All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -🛠 **Wormhole products used:** +## Bug Bounties -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -
-
+If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -
-
+## Learn More -## Bridging Intent Library +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK -🛠 **Wormhole products used:** +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +## Install the SDK -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -
-
+```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` +## Key Components -
-
+The following key components and features work together to make your on-chain Wormhole integration easier to build. -## Multichain Prediction Markets +??? interface "Base contracts" -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -🛠 **Wormhole products used:** +??? interface "Interfaces" -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -
-
+??? interface "Constants" + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -
-
+ - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -## Cross-Chain Payment Widgets +## Example Usage -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: -🛠 **Wormhole products used:** +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +### Set Up a Project -🔗 **Used in:** E-commerce, Web3 payments, and subscription models +Follow these steps to prepare your development environment: -
-
+1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -
-
+2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -## Oracle Networks + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -
-
+ // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -🛠 **Wormhole products used:** + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -
-
+## Use Contracts to Transfer USDC +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -
-
+ ```bash + touch script/transfer.ts + ``` + +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -## Cross-Chain Staking +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -Enable users to stake assets on one chain while earning rewards or securing networks on another. + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -
-
+ // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -🛠 **Wormhole products used:** + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); + + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); + + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` + + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. + +3. Run the script using the following command: + + ```bash + npx tsx script/transfer.ts + ``` + +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! +
-
+ +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. + +## Next Steps + +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-connect.txt b/llms-files/llms-connect.txt index 649c1cb6e..c28adfc08 100644 --- a/llms-files/llms-connect.txt +++ b/llms-files/llms-connect.txt @@ -13,131 +13,290 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-data.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-theme.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/features.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/overview.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/routes.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/upgrade.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect.md [type: tutorials] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/react-dapp.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/tutorials/react-dapp.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/concepts/routes.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/data.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/theme.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/hosted-version.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/upgrade.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/reference/support-matrix.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/transfers/connect/ +Doc-Content: https://wormhole.com/docs/products/connect/tutorials/react-dapp/ --- BEGIN CONTENT --- --- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate multichain asset transfers via Wormhole directly in a web application. +title: Integrate Connect into a React DApp Tutorial +description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. categories: Connect, Transfer --- -# Wormhole Connect +# Integrate Connect into a React DApp -Wormhole Connect is a customizable widget that brings wrapped and native token cross-chain asset transfers into your dApp in as few as 3 lines of code. Connect is available as a React component or hosted version via CDN so you can easily configure any application to transfer tokens via Wormhole. +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -## Build with Connect +## Introduction -[timeline left(wormhole-docs/.snippets/text/build/transfers/connect/connect-timeline.json)] +In this tutorial, we'll explore how to integrate [Wormhole Connect](/docs/products/connect/overview/){target=\_blank} to enable cross-chain token transfers and interactions. Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. -## See It In Action +While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any [blockchain supported by Wormhole](/docs/products/connect/reference/support-matrix/){target=\_blank}. In this example, we'll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. -Wormhole Connect is deployed live in several production apps. Here are a few: +## Prerequisites -- [Portal Bridge](https://portalbridge.com/){target=\_blank} -- [Jupiter](https://jup.ag/onboard/cctp){target=\_blank} -- [Pancake Swap](https://bridge.pancakeswap.finance/wormhole){target=\_blank} +To get started with Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. +Before starting this tutorial, ensure you have the following: -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} page to learn how to combine Connect with other Wormhole products, including Native Token Transfer (NTT). +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use +- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} +- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees -## Next Steps +## Set Up Connect for Sui Transfers -
+### Create a React Project -- :octicons-tools-16:{ .lg .middle} **Get Started Now** +In this tutorial, we'll use [Next.js](https://nextjs.org/docs/app/getting-started){target=\_blank}, a popular framework built on top of React, to set up your app: - --- +1. Open your terminal and run the following command to create a new React app: - Follow this series of how-to guides to integrate Connect into your React dApp and configure options to fit your user's needs. + ```bash + npx create-next-app@latest connect-tutorial + ``` - [:custom-arrow: Get started](/docs/build/transfers/connect/overview/#integrate-connect) + We recommend enabling TypeScript and creating a `src/` directory during setup. Other options can be configured based on your preferences. -- :octicons-tools-16:{ .lg .middle } **Multichain Swap** +2. Navigate into the project directory: - --- + ```bash + cd connect-tutorial + ``` - This tutorial guides you step-by-step through integrating Connect into your React dApp to transfer tokens from Sui to Avalanche Fuji. This tutorial is readily adaptable to work with other [supported networks](/docs/build/start-building/supported-networks/){target=\_blank}. +### Install Connect - [:custom-arrow: Get started](/docs/tutorials/connect/react-dapp/) +Next, install the Connect package as a dependency by running the following command inside your project directory: +```bash +npm install @wormhole-foundation/wormhole-connect +``` + +### Integrate Connect into the Application -- :octicons-tools-16:{ .lg .middle } **Connect FAQs** +Now, we need to modify the default `page.tsx` file to integrate Connect. We are going to use [version V1.0](/docs/products/connect/guides/upgrade/){target=\_blank} or later, make sure to check which version of Connect you are using. Open `src/app/page.tsx` and replace the content with the following code: - --- +=== "JavaScript" + + ```js + 'use client'; - Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. +import WormholeConnect from '@wormhole-foundation/wormhole-connect'; - [:custom-arrow: Visit FAQs](/docs/build/transfers/connect/faqs/) +const config = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], +}; -- :octicons-tools-16:{ .lg .middle } **Supported Features by Chain** +const theme = { + mode: 'light', + primary: '#78c4b6', +}; - --- +export default function Home() { + return ; +} + ``` - Get a more detailed look at Wormhole Connect features with a breakdown of supported features by chain. +=== "TypeScript" - [:custom-arrow: Supported Features](/docs/build/transfers/connect/features/) + ```ts + 'use client'; -
+import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; + +export default function Home() { + const config: WormholeConnectConfig = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], + + ui: { + title: 'SUI Connect TS Demo', + }, + }; + + const theme: WormholeConnectTheme = { + mode: 'light', + primary: '#78c4b6', + }; + return ; +} + ``` + +- Set `network` to `'Testnet'` - this ensures that Connect uses the testnet environment +- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche + +### Customize Connect + +To further customize Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Connect Configuration guide](/docs/products/connect/configuration/data/){target=\_blank}. + +### Run the Application + +Make sure you're in the root directory of your React app, and run the following command to start the application: + +```bash +npm run dev +``` + +Now your React app should be up and running, and Connect should be visible on `http://localhost:3000/`. You should see the Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. + +## Transfer Tokens from Sui to Fuji + +Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. + +To transfer tokens from Sui to Fuji in the Connect interface: + +1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer +2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network +3. Enter the amount of SUI tokens you wish to transfer + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-1.webp){.half} + +4. Choose to view other routes + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-2.webp){.half} + +5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) + + !!! note + It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-3.webp){.half} + +6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-4.webp){.half} + +7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-5.webp){.half} + +Once the transaction has been submitted, Connect will display the progress of the transfer. Monitor the status until you're prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. + +## Claim Tokens on Fuji + +After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. + +![](/docs/images/products/connect/tutorials/react-dapp/connect-6.webp){.half} + +Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. + +![](/docs/images/products/connect/tutorials/react-dapp/connect-7.webp){.half} + +## Resources + +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. + +## Conclusion + +In this tutorial, you've gained hands-on experience with integrating Connect to enable cross-chain token transfers. You've learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. + +By following these steps, you've learned how to: + +- Set up a React project tailored for cross-chain transfers +- Install and configure Connect to support multiple blockchains +- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers +- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks + +With these tools and knowledge, you're now equipped to build powerful cross-chain applications using Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/ +Doc-Content: https://wormhole.com/docs/products/connect/concepts/routes/ --- BEGIN CONTENT --- --- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. +title: Routes +description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. categories: Connect, Transfer --- -# Wormhole Connect +## Routes Overview {: #routes-overview} -## Configure Connect +This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/products/connect/configuration/data/){target=\_blank}. -Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. +Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. -This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. +When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/products/connect/reference/support-matrix/){target=\_blank} to see under which exact conditions the routes appear. -!!! note - To upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for instructions. +## Token Bridge Routes {: #token-bridge-routes} - If you're using an older version of Wormhole Connect (v0.x), please refer to the [v0.x configuration documentation](/docs/build/transfers/connect/configuration-v0/){target=\_blank}. +The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. -
+#### Manual Route {: #manual-route} -- :octicons-database-16:{ .lg .middle } **Data** +The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. - --- +#### Automatic Route {: #automatic-route} - Learn how to configure the networks, tokens, and routes supported by Wormhole Connect. Set up RPC endpoints, whitelist tokens, and leverage multiple bridging protocols to meet your dApp's needs. +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. +## CCTP Routes (USDC) {: #cctp-routes-usdc} + +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. - [:custom-arrow: Get started](/docs/build/transfers/connect/configuration/configure-data/) +Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. -- :octicons-apps-16:{ .lg .middle } **Theme** +#### Manual Route {: #manual-route-cctp} - --- +This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. - Discover how to style the Wormhole Connect widget to align with your brand. Customize colors, fonts, and UI elements to deliver a seamless user experience. +#### Automatic Route {: #automatic-route-cctp} - [:custom-arrow: Explore routes](/docs/build/transfers/connect/configuration/configure-theme/) +Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. -
+## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} + +[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/products/connect/configuration/data/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. + +#### Manual Route {: #manual-route-ntt} + +This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. + +#### Automatic Route {: #automatic-route-ntt} + +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. + +## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} + +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). + +#### Automatic Route {: #automatic-route-eth} + +Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. + +## USDT Bridge Route {: #usdt-bridge-route} + +Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. + +#### Automatic Route {: #automatic-route-usdt} + +Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. + +## tBTC Route {: #tbtc-route} + +You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). + +Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. + +#### Manual Route {: #manual-route-tbtc} + +This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-data/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/data/ --- BEGIN CONTENT --- --- title: Connect Data Configuration @@ -258,18 +417,18 @@ By default, Connect offers two bridging protocols: Token Bridge (for Wormhole-wr The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: -- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank} - manually redeemed Wormhole Token Bridge route -- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank} - automatically redeemed (relayed) Token Bridge route -- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank} - manually redeemed CCTP route -- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank} - automatically redeemed (relayed) CCTP route -- **`DEFAULT_ROUTES`** - array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`) -- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank} - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route -- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}- function that returns the manually-redeemed NTT route -- **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array -- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank} - route that offers multiple Mayan protocols -- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank} - route for Mayan's Swift protocol only -- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank} - route for Mayan's MCTP protocol only -- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank} - route for Mayan's original Wormhole transfer protocol +- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank}: Manually redeemed Wormhole Token Bridge route. +- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank}: Automatically redeemed (relayed) Token Bridge route. +- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank}: Manually redeemed CCTP route. +- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank}: Automatically redeemed (relayed) CCTP route. +- **`DEFAULT_ROUTES`**: Array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`). +- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank}: Function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route. +- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}: Function that returns the manually-redeemed NTT route. +- **`nttRoutes(nttConfig)`**: Function that returns both NTT routes as an array. +- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank}: Route that offers multiple Mayan protocols. +- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank}: Route for Mayan's Swift protocol only. +- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank}: Route for Mayan's MCTP protocol only. +- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank}: Route for Mayan's original Wormhole transfer protocol. In addition to these routes, developers can create custom routes for their Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. @@ -294,7 +453,7 @@ const config: WormholeConnectConfig = { #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript import WormholeConnect, { @@ -500,27 +659,9 @@ Your selected blockchain network determines the available wallet options when us The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. - -### CoinGecko API Key {: #coingecko-api-key } - -The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. - -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; - -const config: WormholeConnectConfig = { - coinGeckoApiKey: 'INSERT_API_KEY', -}; - -function App() { - return ; -} -``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-theme/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/theme/ --- BEGIN CONTENT --- --- title: Connect Theme & UI Customization @@ -530,7 +671,7 @@ categories: Connect, Transfer ## Theme & UI Customization -This page focuses on how to style the Wormhole Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. +This page focuses on how to style the Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. ### Changing the Color Scheme @@ -640,7 +781,7 @@ function App() { ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/faqs/ +Doc-Content: https://wormhole.com/docs/products/connect/faqs/ --- BEGIN CONTENT --- --- title: Connect FAQs @@ -652,7 +793,7 @@ categories: Connect, Transfer ## What types of assets does Connect support? -Wormhole Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: +Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: - Major stablecoins like USDT and USDC (via CCTP) - Native gas tokens such as ETH, SOL, etc. @@ -668,7 +809,7 @@ Connect supports around 30 chains, spanning various blockchain runtimes: - Solana - Move-based chains (Sui, Aptos) -For a complete list of supported chains, see the [Connect-supported chains list](/docs/build/transfers/connect/features/){target=\_blank}. +For a complete list of supported chains, see the [Connect-supported chains list](/docs/products/connect/reference/support-matrix/){target=\_blank}. ## What is gas dropoff? @@ -682,9 +823,9 @@ Connect can be [fully customized](https://connect-in-style.wormhole.com/){target Connect relies on the NTT SDK for integration, with platform-specific implementations for Solana and EVM. The critical methods involved include initiate and redeem functions and rate capacity methods. These functions ensure Connect can handle token transfers and manage chain-rate limits. -## Do integrators need to enable wallets like Phantom or Backpack in Wormhole Connect? +## Do integrators need to enable wallets like Phantom or Backpack in Connect? -Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Wormhole Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. +Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. ## Which function should be modified to set priority fees for Solana transactions? @@ -714,276 +855,201 @@ Additional notes: The TypeScript SDK was previously referred to as the "Connect SDK," but this naming has since been discontinued. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/features/ +Doc-Content: https://wormhole.com/docs/products/connect/get-started/ --- BEGIN CONTENT --- --- -title: Features -description: Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. +title: Get Started with Connect +description: Follow this guide to configure and use the Connect UI widget to easily add an intuitive, multichain asset transfer UI to your web applications. categories: Connect, Transfer --- -## Feature Support Matrix {: #feature-support-matrix} - -*Scroll down for details about each column.* +# Get Started with Connect -| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | -|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| -| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | -| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | -| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | -| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | -| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | -| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | -| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | -| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | -| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | -| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | -| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | -| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | -| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | -| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | -| Base | ✅ | ✅ | ✅ | ✅ | ✅ | -| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | -| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | -| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | -| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -## Feature Explanation {: #feature-explanation} +## Introduction -### Token Bridge {: #token-bridge} +Connect helps you to easily add an intuitive, multichain asset transfer UI to your web applications. The guide demonstrates how to configure the Connect widget, add it to a React application, and view it locally. -Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. +## Install Connect -This route appears if both of the following conditions are satisfied: +To install the [Wormhole Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: - - Both the origin and destination chains support Token Bridge - - No non-Token Bridge routes are available for the selected token +```bash +npm i @wormhole-foundation/wormhole-connect +``` -### Token Bridge Relayer {: #token-bridge-relayer} +## Prerequisites -On the [routes](/docs/build/transfers/connect/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. +Before you begin, make sure you have the following: -Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} -This route appears if all of the following conditions are satisfied: +- (Optional) To test a transfer from your demo app, you'll need: -- Both the origin and destination chains support Token Bridge -- Both the origin and destination chains support Token Bridge relayer -- No non-Token Bridge routes are available for the selected token -- The relayer supports the selected token on the origin chain + - A wallet with [Sui testnet tokens](https://faucet.sui.io/){target=\_blank} + - A wallet with an Avalanche Fuji address (to use as the recipient; no tokens required) -### Circle CCTP {: #circle-cctp} +## Install and Set Up Project -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. +1. Clone the demo repository and navigate to the project directory: -This route appears if all of the following conditions are satisfied: + ```bash + git clone https://github.com/wormhole-foundation/demo-basic-connect.git + cd demo-basic-connect + ``` -- Both the origin and destination chains support Circle CCTP -- The selected token is native Circle-issued USDC +2. Install the dependencies: -### ETH Bridge {: #eth-bridge} + ```bash + npm install + ``` -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. +3. Start the application: -This route appears if all of the following conditions are satisfied: + ```bash + npm start + ``` -- Both the origin and destination chains support the ETH Bridge -- The selected token is native ETH, wstETH, or canonical wETH +4. Open your browser to [localhost:3000](http://localhost:3000){target=\_blank} to view the application locally. It will look similar to the following: -### Gas Drop Off {: #gas-drop-off} + ![Deployed Connect Widget](/docs/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp) -A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. +## Configure Connect -This route appears if all of the following conditions are satisfied: +Open the `App.tsx` file in your code editor of choice. You will see code similar to the following: -- Both the origin and destination chains support gas drop off -- An automatic route is selected -- The relayer accepts the selected token to swap into the gas token ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/connect/overview/ ---- BEGIN CONTENT --- ---- -title: Overview -description: Explore Wormhole Connect, the React widget that allows you to offer an easy-to-use UI for cross-chain asset transfers via Wormhole in a web application. -categories: Connect, Transfer ---- - -# Wormhole Connect - -## Introduction {: #introduction } - -Wormhole Connect is a React widget that lets developers offer an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. Check out the [Wormhole Connect GitHub repository](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. - -The [Wormhole TypeScript SDK](https://docs.wormhole.com/wormhole/reference/sdk-docs){target=\_blank} allows you to implement the same functionality as the Connect widget but in your own UI. Check out the docs for more information on using the SDK instead of Connect. - -## Features {: #features } - -Wormhole Connect is easy to customize to suit your application's needs. You can specify technical details like supported assets and custom RPCs or forgo customization and have a full-featured widget. The widget UI is highly customizable, with extensive styling options available, including a user-friendly no code styling interface for those who prefer a more visual approach to design. The features of Wormhole Connect include: - -- Multiple ways to bridge assets ([routes](/docs/build/transfers/connect/routes/){target=\_blank}) -- Extensive ways to style the UI (including the [no code styling interface](https://connect-in-style.wormhole.com/){target=\_blank}) -- Ways to [configure](/docs/build/transfers/connect/configuration/){target=\_blank} what feature set to offer -- Ability to configure any token to bridge via Wormhole -- [Ability to drop off some gas](/docs/build/transfers/connect/features/){target=\_blank} at the destination - -For more details about the features of Wormhole Connect and a breakdown of supported features by chain, be sure to check [the features page](/docs/build/transfers/connect/features/){target=\_blank}. - -## Integrate Connect {: #integrate-connect } - -### Import Directly into a React App {: #import-directly-into-a-react-app} - -First, install the Wormhole Connect npm package. You can read more about the package by clicking on the following button: [![npm version](https://img.shields.io/npm/v/@wormhole-foundation/wormhole-connect.svg)](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} - -```bash -npm i @wormhole-foundation/wormhole-connect -``` - -Now you can import the React component: - -```ts -import WormholeConnect from '@wormhole-foundation/wormhole-connect'; +```typescript title="App.tsx" +import './App.css'; +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; function App() { - return ; -} -``` + const config: WormholeConnectConfig = { + // Define the network + network: 'Testnet', -### Use Hosted Version via CDN {: #use-hosted-version-via-cdn} + // Define the chains + chains: ['Sui', 'Avalanche'], -If you're not using React, you can still embed Connect on your website by using the hosted version. This uses pre-built packages (which include React) served from NPM by jsdelivr.net. + // UI configuration + ui: { + title: 'SUI Connect TS Demo', + }, + }; -```ts title="v1.x" -import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; + const theme: WormholeConnectTheme = { + // Define the theme + mode: 'dark', + primary: '#78c4b6', + }; -// Existing DOM element where you want to mount Connect -const container = document.getElementById('bridge-container'); + return ; +} -wormholeConnectHosted(container); +export default App; ``` -For help migrating from Connect v0.x to v1.x, see the [v1 Migration](/docs/build/transfers/connect/upgrade/){target=\_blank} guide. - -???- code "v0.x" - Simply copy and paste the following into your HTML body, and replace the ```INSERT_WORMHOLE_CONNECT_VERSION``` in the links with the most recent production version of Wormhole Connect. You can check what the most recent version is on [NPM](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/latest){target=\_blank}. +The preceding sample code configures Connect by setting values inside `config` and `theme` as follows: - ```html - -
- - - - ``` - - For example, for [0.3.13](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/0.3.13){target=\_blank}: - - ```html - -
- - - - ``` +- **Defines the network**: Options include `Mainnet`, `Testnet`, or `Devnet`. +- **Defines chains to include**: This example uses Sui and Avalanche. See the complete list of [Connect-supported chain names](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank} if you would like to use different chains. +- **Adds a title to UI**: (Optional) If defined, it will render above the widget in the UI. +- **Defines the theme**: This example sets the mode to `dark` and adds a primary color. -It is important to periodically update your Wormhole Connect instance to the latest version, as there are frequent functionality and security releases. +## Interact with Connect -## Configuration {: #configuration} +Congratulations! You've successfully used Connect to create a simple multichain token transfer application. You can now follow the prompts in the UI to connect your developer wallets and send a test transfer. -This is just an overview of what's possible. Check the [Configuration docs](/docs/build/transfers/connect/configuration/){target=\_blank} for details about all the configuration options. +## Next Steps -The default configuration of Wormhole Connect may not be exactly what you're looking for. You may want to: +Use the following guides to configure your Connect instance and integrate it into your application: - - Use custom styles - - Restrict the chains that you allow in your app - - Add support for your project's token, and eliminate tokens you don't want to reduce noise - - Configuring custom RPC URLs (This is highly recommended as default public RPCs are heavily throttled) - - Restrict the [routes](/docs/build/transfers/connect/routes/){target=\_blank} that are available +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. +- **[Integrate Connect into a React DApp](/docs/products/connect/tutorials/react-dapp/)**: Learn how to integrate Connect into a React application, including setting up the widget and handling transfers. -For additional information on the preceding options, check the [configuration options](/docs/build/transfers/connect/configuration/){target=\_blank} and customize your widget however you like. + --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/routes/ +Doc-Content: https://wormhole.com/docs/products/connect/guides/hosted-version/ --- BEGIN CONTENT --- --- -title: Routes -description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. +title: Integrate Connect via CDN +description: categories: Connect, Transfer --- -## Routes Overview {: #routes-overview} - -This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/build/transfers/connect/configuration/){target=\_blank}. - -Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. - -When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/build/transfers/connect/features/){target=\_blank} to see under which exact conditions the routes appear. - -## Token Bridge Routes {: #token-bridge-routes} - -The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. - -#### Manual Route {: #manual-route} - -The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. - -#### Automatic Route {: #automatic-route} - -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. - -## CCTP Routes (USDC) {: #cctp-routes-usdc} - -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. - -Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. - -#### Manual Route {: #manual-route-cctp} - -This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. - -#### Automatic Route {: #automatic-route-cctp} - -Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. - -## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} +# Integrate Connect via CDN -[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/build/transfers/connect/configuration/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. +[Wormhole Connect](/docs/products/connect/overview/){target=\_blank} is a prebuilt UI component that makes it easy to transfer tokens across chains. You can integrate it into any website using either React or a hosted version served via [jsDelivr](https://www.jsdelivr.com/){target=\_blank}. -#### Manual Route {: #manual-route-ntt} +This guide focuses on using the hosted version—ideal for simpler setups or non-React environments. It includes everything you need to get started with just a few lines of code. -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. +If you're using React, refer to the [Get Started with Connect](/docs/products/connect/get-started/){target=\_blank} guide. -#### Automatic Route {: #automatic-route-ntt} +## Install Connect -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. +To install the [Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: -## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} +```bash +npm i @wormhole-foundation/wormhole-connect +``` -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). +## Add Connect to Your Project Using the Hosted Version -#### Automatic Route {: #automatic-route-eth} +The hosted version uses pre-built packages (including React) served via jsDelivr from npm. To integrate it without using React directly, add the following to your JavaScript project: -Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. +```js +import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; -## USDT Bridge Route {: #usdt-bridge-route} +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'bridge-container' not found"); +} -Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. +wormholeConnectHosted(container); +``` -#### Automatic Route {: #automatic-route-usdt} +You can provide config and theme parameters in a second function argument: -Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. +```js +import { + wormholeConnectHosted, +} from '@wormhole-foundation/wormhole-connect'; -## tBTC Route {: #tbtc-route} +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'connect' not found"); +} -You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). +wormholeConnectHosted(container, { + config: { + rpcs: { + // ... + } + }, + theme: { + background: { + default: '#004547', + } + } +}); +``` -Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. +## Next Steps -#### Manual Route {: #manual-route-tbtc} +Use the following guides to configure your Connect instance: -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/upgrade/ +Doc-Content: https://wormhole.com/docs/products/connect/guides/upgrade/ --- BEGIN CONTENT --- --- title: Wormhole Connect v1.0 Migration Guide @@ -1005,11 +1071,9 @@ This guide will help you migrate to the new version in just a few simple steps. These updates ensure better performance and a smoother integration experience. -For complete documentation on the previous version of Wormhole Connect, please refer to the [Wormhole Connect guide](/docs/build/transfers/connect/){target=\_blank}. - ## Update the Connect Package -To begin the migration process, update the Wormhole Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. +To begin the migration process, update the Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. Run the following command in your terminal: @@ -1112,12 +1176,12 @@ The `networks` property, which allowed whitelisting chains, is now renamed `chai ### Update `routes` to Use Route Plugins -The `routes` property in Wormhole Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. +The `routes` property in Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. -By default, if no `routes` property is set, Wormhole Connect will provide routes for two core protocols: +By default, if no `routes` property is set, Connect will provide routes for two core protocols: - - [Wormhole Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} - - [CCTP](/docs/learn/transfers/cctp/){target=\_blank} + - [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} + - [CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} For most use cases, integrators require more than the default routes. The new `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including both default and third-party routes. @@ -1126,7 +1190,7 @@ For most use cases, integrators require more than the default routes. The new `r The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: ???- tip "`route` Plugins" - - **`TokenBridgeRoute`** - manually redeemed Wormhole Token Bridge route + - **`TokenBridgeRoute`** - manually redeemed Token Bridge route - **`AutomaticTokenBridgeRoute`** - automatically redeemed (relayed) Token Bridge route - **`CCTPRoute`** - manually redeemed CCTP route - **`AutomaticCCTPRoute`** - automatically redeemed (relayed) CCTP route @@ -1147,7 +1211,7 @@ Now that you know the available `route` plugins, let's explore some examples of #### Example: Offer Only CCTP Transfers -To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: +To configure Connect to offer only USDC transfers via the CCTP route, use the following configuration: ```typescript import WormholeConnect, { @@ -1164,7 +1228,7 @@ const config: WormholeConnectConfig = { #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript import WormholeConnect, { @@ -1187,7 +1251,7 @@ This flexible plugin allows you to combine default routes (such as Token Bridge ### Update the `tokensConfig` Structure -In Wormhole Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. +In Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. Key Changes to `tokensConfig`: @@ -1264,7 +1328,7 @@ Key Changes to `tokensConfig`: ### Update NTT Configuration -In Wormhole Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. +In Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. Key changes: @@ -1363,7 +1427,7 @@ This change simplifies the configuration process by providing a cleaner, more fl ### Update UI Configuration -In Wormhole Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. +In Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. Key UI changes: @@ -1487,7 +1551,7 @@ Important details: ### Removed Configuration Properties -Several configuration properties have been removed in Wormhole Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. +Several configuration properties have been removed in Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. Removed config keys: @@ -1515,7 +1579,7 @@ For those using the CDN-hosted version of Wormhole Connect, the package's instal npm install @wormhole-foundation/wormhole-connect@^1.0 ``` -2. After installing the package, you can embed Wormhole Connect into your page by adding the following code: +2. After installing the package, you can embed Connect into your page by adding the following code: ```typescript import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; @@ -1555,2330 +1619,2652 @@ wormholeConnectHosted(container, { In this example, the `config` object defines the routes (in this case, using the Mayan route), while the `theme` object allows customization of the Connect interface (e.g., background color). --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/connect/ +Doc-Content: https://wormhole.com/docs/products/connect/overview/ --- BEGIN CONTENT --- --- -title: Wormhole Connect Tutorials -description: Enable cross-chain connectivity with Wormhole Connect. Learn integration and simplify user experiences across multiple blockchains. +title: Wormhole Connect +description: With Wormhole Connect, you can seamlessly bridge digital assets and data across a wide range of supported blockchain networks. categories: Connect, Transfer --- -# Connect +# Connect Overview -Wormhole Connect makes it simple to link your application to multiple blockchain ecosystems. These tutorials will teach you how to integrate Connect into your projects, streamline cross-chain interactions, simplify user onboarding, and deliver a smoother overall experience. +With the Wormhole Connect widget, you can enable users to perform multichain asset transfers directly within your application. Connect simplifies the complexity of bridging, offering a single, intuitive point of interaction for moving assets across diverse blockchains. This empowers you to access liquidity and opportunities across any connected network seamlessly. -## Tutorials +## Key Features -
+Connect's notable features include: -- :octicons-repo-16:{ .lg .middle } **Integrate Connect into a React DApp** +- **In-app multichain transfers**: Bridge assets without leaving your app. +- **Customizable features**: Specify chains and custom RPCs, manage tokens, and select bridging [routes](/docs/products/connect/concepts/routes/){target=\_blank} such as Token Bridge, CCTP, or NTT. +- **Customizable UI**: Style the bridge interface to match your brand. +- **Optional destination gas**: Provide gas for initial transactions on the target chain. +- **Wrapped and native assets support**: Supports both wrapped and native tokens and integrates with Settlement. - --- +Be sure to check the [Feature Support Matrix](/docs/products/connect/reference/support-matrix/#feature-support-matrix){target=\_blank} to find out which routes and features are supported for each chain. - Learn how to incorporate Wormhole Connect into a React application. This step-by-step tutorial guides you through enabling cross-chain token transfers and interactions, bridging assets between networks, and enhancing the user experience with streamlined blockchain connectivity. +## How It Works - [:custom-arrow: Start building](/docs/tutorials/connect/react-dapp/) +When a user initiates a multichain transfer, Connect walks them through key steps and automates the transfer process behind the scenes, including: -
+1. **Initiating the transfer**: Connect your chosen wallet to the source chain, select asset and source chain for the transfer. +2. **Finalize transfer setup**: Connect the destination wallet, select the target chain and select a bridging route (manual or automatic). +3. **Transaction submission on source chain**: Confirms the transfer details to trigger the asset lock or deposit on the initial blockchain. Connect will guide you through the transaction process. +4. **VAA or attestation creation**: Wormhole [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the source transaction and produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. +5. **Relaying to destination**: The VAA or attestation is automatically relayed to the destination chain. +6. **Verification on destination**: Contracts on the target chain receive and verify the incoming VAA. +7. **Asset release/minting**: Upon successful verification, the equivalent assets are either released or minted on the target chain and delivered to your wallet. -## Additional Resources +!!! tip + If you want more hands on experience with Connect, checkout [Portal Bridge](https://portalbridge.com/){target=\_blank}. -
+## Use Cases -- :octicons-tools-16:{ .lg .middle } **Connect** +Here are some key use cases that highlight the power and versatility of Connect: - --- +- **Cross-Chain Swaps and Liquidity Aggregation** - Get deeper insights into setting up and customizing Wormhole Connect. Explore advanced guides, best practices, and configuration tips to streamline your cross-chain integrations. + - [**Connect**](/docs/products/connect/get-started/): Handles user-friendly asset transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Moves native assets across chains. + - [**Queries**](/docs/products/queries/overview/): Fetches real-time prices for optimal trade execution. - [:custom-arrow: Learn more](/docs/build/transfers/connect/) +- **Cross-Chain Payment Widgets** -
+ - [**Connect**](/docs/products/connect/get-started/): Facilitates seamless payments in various tokens. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Ensures direct, native asset transfers. + +- **Web3 Game Asset Transfers** + + - [**Connect**](/docs/products/connect/get-started/): Provide a user-friendly way to move game tokens across chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/): Handle the underlying lock-and-mint logic securely. + +## Next Steps + +Add Connect to your app with these key setup steps: + +[timeline(wormhole-docs/.snippets/text/products/connect/overview/connect-timeline.json)] --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/connect/react-dapp/ +Doc-Content: https://wormhole.com/docs/products/connect/reference/support-matrix/ --- BEGIN CONTENT --- --- -title: Integrate Connect into a React DApp Tutorial -description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. +title: Features +description: Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. categories: Connect, Transfer --- -# Integrate Connect into a React DApp +## Feature Support Matrix {: #feature-support-matrix} -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} +*Scroll down for details about each column.* -## Introduction +| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | +|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| +| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | +| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | +| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | +| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | +| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | +| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | +| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | +| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | +| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | +| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | +| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | +| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | +| Base | ✅ | ✅ | ✅ | ✅ | ✅ | +| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | +| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | +| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | +| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | -In this tutorial, we’ll explore how to integrate [Wormhole Connect](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank} to enable cross-chain token transfers and interactions. Wormhole Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Wormhole Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. +## Feature Explanation {: #feature-explanation} -While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any blockchain supported by Wormhole. In this example, we’ll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. +### Token Bridge {: #token-bridge} -## Prerequisites +Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. -To get started with Wormhole Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. -Before starting this tutorial, ensure you have the following: +This route appears if both of the following conditions are satisfied: -- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine -- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use -- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} -- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees + - Both the origin and destination chains support Token Bridge + - No non-Token Bridge routes are available for the selected token -## Set Up Connect for Sui Transfers +### Token Bridge Relayer {: #token-bridge-relayer} -### Create a React Project +On the [routes](/docs/products/connect/concepts/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. -Start by setting up your React app: +Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. -1. Open your terminal and run the following command to create a new React app: +This route appears if all of the following conditions are satisfied: - ```bash - npx create-react-app connect-tutorial - ``` +- Both the origin and destination chains support Token Bridge +- Both the origin and destination chains support Token Bridge relayer +- No non-Token Bridge routes are available for the selected token +- The relayer supports the selected token on the origin chain -2. Navigate into the project directory: +### Circle CCTP {: #circle-cctp} - ```bash - cd connect-tutorial - ``` +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. -### Install Wormhole Connect +This route appears if all of the following conditions are satisfied: -Next, install the Wormhole Connect package as a dependency by running the following command inside your project directory: +- Both the origin and destination chains support Circle CCTP +- The selected token is native Circle-issued USDC -```bash -npm install @wormhole-foundation/wormhole-connect -``` +### ETH Bridge {: #eth-bridge} -### Integrate Connect into the Application +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. -Now, we need to modify the default `App.js` file to integrate Wormhole Connect. We are going to use [version V1.0](/docs/build/transfers/connect/upgrade/){target=\_blank}, make sure to check which version of connect you are using. Open `src/App.js` and replace the content with the following code: +This route appears if all of the following conditions are satisfied: -=== "JavaScript" +- Both the origin and destination chains support the ETH Bridge +- The selected token is native ETH, wstETH, or canonical wETH - ```js - import logo from './logo.svg'; - import './App.css'; - import WormholeConnect from '@wormhole-foundation/wormhole-connect'; +### Gas Drop Off {: #gas-drop-off} - const config = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], - }; +A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. - function App() { - return ; - } +This route appears if all of the following conditions are satisfied: - export default App; - ``` +- Both the origin and destination chains support gas drop off +- An automatic route is selected +- The relayer accepts the selected token to swap into the gas token +--- END CONTENT --- -=== "TypeScript" +## Basics Concepts [shared: true] - ```ts - import './App.css'; - import WormholeConnect, { - WormholeConnectConfig, - WormholeConnectTheme, - } from '@wormhole-foundation/wormhole-connect'; +The following section contains foundational documentation shared across all Wormhole products. +It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. +This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. +This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. - function App() { - const config: WormholeConnectConfig = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], +--- - ui: { - title: 'SUI Connect TS Demo', - }, - }; +## List of shared concept pages: - const theme: WormholeConnectTheme = { - mode: 'dark', - primary: '#78c4b6', - }; - return ; - } +## Full content for shared concepts: - export default App; - ``` +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK +--- -- Set `network` to `testnet` - this ensures that Wormhole Connect uses the testnet environment -- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche +# Get Started with Messaging -### Customize Wormhole Connect +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -To further customize Wormhole Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Wormhole Connect Configuration guide](/docs/build/transfers/connect/configuration/#introduction){target=\_blank}. +## Prerequisites -### Run the Application +Before you begin, ensure you have the following: -Make sure you’re in the root directory of your React app, and run the following command to start the application: +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -```bash -npm start -``` +## Configure Your Messaging Environment -Now your React app should be up and running, and Wormhole Connect should be visible on `http://localhost:3000/`. You should see the Wormhole Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. +1. Create a directory and initialize a Node.js project: -## Transfer Tokens from Sui to Fuji + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -To transfer tokens from Sui to Fuji in the Wormhole Connect interface: + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer -2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network -3. Enter the amount of SUI tokens you wish to transfer +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: - ![](/docs/images/tutorials/connect/react-dapp/connect-1.webp) - -4. Choose to view other routes - - ![](/docs/images/tutorials/connect/react-dapp/connect-2.webp) + ```bash + npx tsc --init + ``` -5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` - !!! note - It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: - ![](/docs/images/tutorials/connect/react-dapp/connect-3.webp) + ```bash + npm install @wormhole-foundation/sdk + ``` -6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain +5. Create a new file named `main.ts`: - ![](/docs/images/tutorials/connect/react-dapp/connect-4.webp) + ```bash + touch main.ts + ``` -7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } - ![](/docs/images/tutorials/connect/react-dapp/connect-5.webp) + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -Once the transaction has been submitted, Wormhole Connect will display the progress of the transfer. Monitor the status until you’re prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } -## Claim Tokens on Fuji + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); -After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; -![](/docs/images/tutorials/connect/react-dapp/connect-6.webp) + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); -Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -![](/docs/images/tutorials/connect/react-dapp/connect-7.webp) + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -## Resources + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Wormhole Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -## Conclusion + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -In this tutorial, you’ve gained hands-on experience with integrating Wormhole Connect to enable cross-chain token transfers. You’ve learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -By following these steps, you've learned how to: +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -- Set up a React project tailored for cross-chain transfers -- Install and configure Wormhole Connect to support multiple blockchains -- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers -- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -With these tools and knowledge, you’re now equipped to build powerful cross-chain applications using Wormhole Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. ---- END CONTENT --- +2. Run the script using the following command: -## Basics Concepts [shared: true] + ```bash + npx tsx main.ts + ``` -The following section contains foundational documentation shared across all Wormhole products. -It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. -This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. -This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
---- +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -## List of shared concept pages: +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. +## Next Steps -## Full content for shared concepts: +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Glossary - -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - -## Chain ID - -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. - -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. - -## Consistency Level - -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. - -## Delivery Provider - -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. - -## Emitter - -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +# Get Started with Core Contracts -## Finality +## Introduction -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -## Guardian +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -## Guardian Network +## Prerequisites -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +To interact with the Wormhole Core Contract, you'll need the following: -## Guardian Set +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## How to Interact with Core Contracts -## Heartbeat +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -## Observation +### Sending Messages -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -## Relayer +=== "EVM" -A relayer is any process that delivers VAAs to a destination. + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -## Sequence + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + ??? interface "Parameters" -## Spy + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + --- -## VAA + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. + --- -## Validator + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. ---- END CONTENT --- + ??? interface "Returns" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ ---- BEGIN CONTENT --- ---- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics ---- + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -# Infrastructure Components + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -## Get Started +// Check fee and send parameters -Start here for an overview of Wormhole architecture components and security mechanisms: +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -
+// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` - --- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +=== "Solana" - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -- :octicons-book-16:{ .lg .middle } **Security** + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` - --- + ??? interface "Parameters" - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - [:custom-arrow: Learn About Security](/docs/learn/security/) + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -
+ ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -## Explore Components + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: + ??? child "Type `PostMessage<'info>`" -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -## Next Steps + --- -
+ `batch_id` ++"u32"++ + + An identifier for the message batch. -- :octicons-book-16:{ .lg .middle } **Messaging Components** + --- - --- + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + --- - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" - --- + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -
---- END CONTENT --- +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -# Architecture +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -## Overview +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +### Receiving Messages -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +The way a message is received and handled depends on the environment. -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +=== "EVM" -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + ??? interface "Parameters" -## On-Chain Components + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + ??? interface "Returns" -## Off-Chain Components + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + ??? child "Struct `VM`" -## Next Steps + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -
+ For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -- :octicons-book-16:{ .lg .middle } **Core Contracts** + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- - --- + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + ??? interface "Example" - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + // Perform safety checks here - --- + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + // Your custom application logic here +} + ``` - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -
---- END CONTENT --- +=== "Solana" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -# Core Contracts + Retrieve the raw message data: -## Introduction + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. + ??? interface "Example" -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -## Key Functions + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -Key functions of the Wormhole Core Contract include the following: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +#### Validating the Emitter -## How the Core Contract Works +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -The following describes the role of the Wormhole Core Contract in message transfers: +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -### Message Submission +await tx.wait(); +``` -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: +#### Additional Checks -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -### Message Reception +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. +## Source Code References -## Multicast +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. +# Wormhole Relayer -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. +## Introduction -## Next Steps +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -
+This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** +## Get Started with the Wormhole Relayer - --- +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** +### Wormhole Relayer Interfaces - --- +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) +## Interact with the Wormhole Relayer -
---- END CONTENT --- +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -## Guardian +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +Your initial set up should resemble the following: -Guardians fulfill their role in the messaging protocol as follows: +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +contract Example { + IWormholeRelayer public wormholeRelayer; -## Guardian Network + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -The Guardian Network is designed to help Wormhole deliver on five key principles: +### Send a Message -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -The following sections explore each principle in detail. +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -### Decentralization +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -Two common approaches to decentralization have notable limitations: +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -To answer that, consider these key constraints and design decisions: +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +### Receive a Message -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -### Modularity +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -### Chain Agnosticism +## Delivery Guarantees -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -### Scalability +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +## Delivery Statuses -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -### Upgradeable +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -Wormhole is designed to adapt and evolve in the following ways: +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -## Next Steps +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -
+## Other Considerations -- :octicons-book-16:{ .lg .middle } **Relayers** +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: - --- +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +## Track the Progress of Messages with the Wormhole CLI - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** +=== "Mainnet" - --- + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +=== "Testnet" - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -
+See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. + +## Step-by-Step Tutorial + +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ --- BEGIN CONTENT --- --- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. categories: Basics --- -# Relayers +# Messaging Overview -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +## Key Features -There are three primary types of relayers discussed: +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +## How It Works -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +The messaging flow consists of several core components: -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -## Fundamentals +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +## Use Cases -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -Key characteristics of VAAs include: +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -- Public emission from the Guardian Network + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- Authentication through signatures from the Guardian Network +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- Verifiability by any entity or any Wormhole Core Contract + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +- **Gas Abstraction** -Keep in mind the following security considerations around relayers: + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- **Bridging Intent Library** -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -## Client-Side Relaying + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +## Next Steps -### Key Features +Follow these steps to work with Wormhole Messaging: -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Implementation +# Products -Users themselves carry out the three steps of the cross-chain process: +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -1. Perform an action on chain A +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -2. Retrieve the resulting VAA from the Guardian Network +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -3. Perform an action on chain B using the VAA +## Transfer Products -### Considerations +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -- Users must sign all required transactions with their own wallet +
-- Users must have funds to pay the transaction fees on every chain involved +::spantable:: -- The user experience may be cumbersome due to the manual steps involved +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | -## Custom Relayers +::end-spantable:: -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +
-The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: -### Key Features +
-- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +## Bridging UI -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +## Real-time Data -### Implementation +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +## Multichain Governance -### Considerations +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ +--- BEGIN CONTENT --- +--- +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +categories: Basics +--- -- Development work and hosting of relayers are required +# Glossary -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +## Chain ID -## Wormhole Relayers +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -### Key Features +## Consistency Level -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +## Delivery Provider -### Implementation +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -The Wormhole relayer integration involves two key steps: +## Emitter -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +## Finality -### Considerations +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +## Guardian -- All computations are performed on-chain +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -- Potentially less gas-efficient compared to custom relayers +## Guardian Network -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -- Support may not be available for all chains +## Guardian Set -## Next Steps +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -
+## Heartbeat -- :octicons-book-16:{ .lg .middle } **Spy** +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - --- +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +## Observation - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +## Relayer - --- +A relayer is any process that delivers VAAs to a destination. - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +## Sequence - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +## Spy - --- +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +## VAA - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -
+## Validator + +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/protocol/architecture/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. categories: Basics --- -# Spy - -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - -## Key Features - -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +# Architecture -## Integrator Use Case +## Overview -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -## Observable Message Categories +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -A Spy can access the following categories of messages shared over the gossip protocol: +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +## On-Chain Components - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +## Off-Chain Components - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Additional Resources +## Next Steps
-- :octicons-code-16:{ .lg .middle } **Spy Source Code** +- :octicons-book-16:{ .lg .middle } **Core Contracts** --- - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +- :octicons-tools-16:{ .lg .middle } **Core Messaging** --- - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. - - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) - --- +
+--- END CONTENT --- - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +# The Wormhole Ecosystem -
+[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -## Next Steps +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-code-16:{ .lg .middle } **Run a Spy** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-code-16:{ .lg .middle } **Use Queries** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. categories: Basics --- -# Verified Action Approvals +# Core Contracts -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. +## Introduction -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Key Functions -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +Key functions of the Wormhole Core Contract include the following: -## VAA Format +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -The basic VAA consists of header and body components described as follows: +## How the Core Contract Works -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. - Where each `signature` is: +The following describes the role of the Wormhole Core Contract in message transfers: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +### Message Submission -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -## Consistency and Finality +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +### Message Reception -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Signatures +## Multicast -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -## Payload Types +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +## Next Steps -### Token Transfer +
-Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** -Transferring tokens from the sending chain to the destination chain requires the following steps: + --- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. + --- -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -### Attestation + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +
+--- END CONTENT --- -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ +--- BEGIN CONTENT --- +--- +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +categories: Basics +--- -The message format for token attestation is as follows: +## Guardian -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -#### Attestation Tips +Guardians fulfill their role in the messaging protocol as follows: -Be aware of the following considerations when working with attestations: +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +## Guardian Network -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +The Guardian Network is designed to help Wormhole deliver on five key principles: -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Token Transfer with Message +The following sections explore each principle in detail. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +### Decentralization -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +Two common approaches to decentralization have notable limitations: -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -### Governance +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -#### Action Structure +To answer that, consider these key constraints and design decisions: -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +### Modularity -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -#### Actions +### Chain Agnosticism -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +### Scalability -## Lifetime of a Message +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +### Upgradeable + +Wormhole is designed to adapt and evolve in the following ways: -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Relayers** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Queries](/docs/products/queries/overview/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Introduction to Wormhole +# Relayers -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +There are three primary types of relayers discussed: -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## Fundamentals -## What Problems Does Wormhole Solve? +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -Critical problems Wormhole addresses include: +Key characteristics of VAAs include: -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +- Public emission from the Guardian Network -## What Does Wormhole Offer? +- Authentication through signatures from the Guardian Network -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- Verifiability by any entity or any Wormhole Core Contract -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -## What Isn't Wormhole? +Keep in mind the following security considerations around relayers: -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## Use Cases of Wormhole +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -Consider the following examples of potential applications enabled by Wormhole: +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +## Client-Side Relaying -## Explore +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -Discover more about the Wormhole ecosystem, components, and protocols: +### Key Features -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -## Demos +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -Demos offer more realistic implementations than tutorials: +### Implementation -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +Users themselves carry out the three steps of the cross-chain process: - +2. Retrieve the resulting VAA from the Guardian Network -!!! note - Wormhole Integration Complete? +3. Perform an action on chain B using the VAA - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +### Considerations - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. + +- Users must sign all required transactions with their own wallet -## Supported Blockchains +- Users must have funds to pay the transaction fees on every chain involved -Wormhole supports a growing number of blockchains. +- The user experience may be cumbersome due to the manual steps involved -text/supported-networks.md ---- END CONTENT --- +## Custom Relayers -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -# Security +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -## Core Security Assumptions +### Key Features -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more -In summary: +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +### Implementation -## Guardian Network +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +### Considerations -### Governance +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +- Development work and hosting of relayers are required -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +- Relayers are responsible for availability, and adding dependencies for the cross-chain application -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +## Wormhole Relayers -Via governance, the Guardians can: +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +### Key Features -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -## Monitoring +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +### Implementation -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +The Wormhole relayer integration involves two key steps: -Guardians monitor: +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -## Asset Layer Protections +### Considerations -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +- All computations are performed on-chain -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +- Potentially less gas-efficient compared to custom relayers -## Open Source +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted -Wormhole builds in the open and is always open source. +- Support may not be available for all chains -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +## Next Steps -## Audits +
-Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +- :octicons-book-16:{ .lg .middle } **Spy** -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} + --- -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -## Bug Bounties + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + --- -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) -## Learn More +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. + --- + + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. + + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. categories: Basics --- -# Get Started with Core Contracts - -## Introduction +# Spy -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. -## Prerequisites +## Key Features -To interact with the Wormhole Core Contract, you'll need the following: - -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - -## How to Interact with Core Contracts - -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network - -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. - -### Sending Messages - -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. - -=== "EVM" - - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: - - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` - - ??? interface "Parameters" - - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. - - --- - - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - - --- - - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - - ??? interface "Returns" - - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" - - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); - -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); - -// Check fee and send parameters - -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); - -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); - -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - -=== "Solana" - - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: - - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` - - ??? interface "Parameters" - - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" - - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. - - ??? child "Type `PostMessage<'info>`" - - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - - --- - - `batch_id` ++"u32"++ - - An identifier for the message batch. - - --- - - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. - - --- - - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" - - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" - - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" - - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters - -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; - -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. - -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. - -### Receiving Messages - -The way a message is received and handled depends on the environment. - -=== "EVM" - - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. - - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` - - ??? interface "Parameters" - - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. - - ??? interface "Returns" - - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. - - ??? child "Struct `VM`" - - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` - - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. - - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- - - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided - - ??? interface "Example" - - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); - - // Perform safety checks here - - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); - - // Your custom application logic here -} - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - -=== "Solana" - - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - Retrieve the raw message data: +## Integrator Use Case - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ??? interface "Example" +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +## Observable Message Categories - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +A Spy can access the following categories of messages shared over the gossip protocol: - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data -#### Validating the Emitter + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +## Additional Resources -await tx.wait(); -``` +
-#### Additional Checks +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + --- -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -## Source Code References +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + --- -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -# Wormhole Relayer +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -## Introduction + --- -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -## Get Started with the Wormhole Relayer +
-Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +## Next Steps -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +
-
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+- :octicons-code-16:{ .lg .middle } **Run a Spy** -### Wormhole Relayer Interfaces + --- -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -## Interact with the Wormhole Relayer +- :octicons-code-16:{ .lg .middle } **Use Queries** -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + --- -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -Your initial set up should resemble the following: +
+--- END CONTENT --- -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +# Verified Action Approvals -contract Example { - IWormholeRelayer public wormholeRelayer; +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -### Send a Message +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +## VAA Format -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +The basic VAA consists of header and body components described as follows: -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` + Where each `signature` is: -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -### Receive a Message +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +## Consistency and Finality -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -## Delivery Guarantees +## Signatures -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -## Delivery Statuses +## Payload Types -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +### Token Transfer -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +Transferring tokens from the sending chain to the destination chain requires the following steps: -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: + +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -## Other Considerations +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +### Attestation -## Track the Progress of Messages with the Wormhole CLI +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -=== "Mainnet" +The message format for token attestation is as follows: - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -=== "Testnet" +#### Attestation Tips - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +Be aware of the following considerations when working with attestations: -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -## Step-by-Step Tutorial +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -# Products +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +### Token Transfer with Message -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -## Transfer Products +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +### Governance -
+Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -::spantable:: +#### Action Structure -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -::end-spantable:: +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -
+Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Bridging UI +#### Actions -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -## Real-time Data +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +## Lifetime of a Message -## Multichain Governance +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -# Wormhole Use Cases +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -
-
+## Next Steps -## Cross-Chain Swaps and Liquidity Aggregation +
-Enable seamless swaps between chains with real-time liquidity routing. +- :octicons-book-16:{ .lg .middle } **Guardians** -
-
+ --- -🛠 **Wormhole products used:** + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -
-
+ --- + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -
-
+ [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -## Borrowing and Lending Across Chains +
+--- END CONTENT --- -Let users borrow assets on one chain using collateral from another. +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -
-
+# Introduction to Wormhole -🛠 **Wormhole products used:** +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -
-
+![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -
-
+Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -## Real-Time Price Feeds and Trading Strategies +This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -Fetch price feeds across multiple chains for DeFi applications. +## What Problems Does Wormhole Solve? -
-
+Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -🛠 **Wormhole products used:** +Critical problems Wormhole addresses include: -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +## What Does Wormhole Offer? -
-
+Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -
-
+## What Isn't Wormhole? -## Asset Movement Between Bitcoin and Other Chains +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -Enable direct BTC transfers without wrapped assets. +## Use Cases of Wormhole -
-
+Consider the following examples of potential applications enabled by Wormhole: -🛠 **Wormhole products used:** +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +## Explore -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +Discover more about the Wormhole ecosystem, components, and protocols: -
-
+- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -## Decentralized Social Platforms +Demos offer more realistic implementations than tutorials: -Enable seamless communication and asset transfer across decentralized social networks. +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -
-
+ -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +!!! note + Wormhole Integration Complete? -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +## Supported Networks by Product -
-
+Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -## Memecoin Launchpads +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +# Security -
-
+## Core Security Assumptions -🛠 **Wormhole products used:** +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -
-
+## Guardian Network -## Cross-Chain Perpetuals +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +### Governance -
-
+Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -🛠 **Wormhole products used:** +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -
-
+The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -## Gas Abstraction +## Monitoring -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -
-
+Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -🛠 **Wormhole products used:** +Guardians monitor: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +## Asset Layer Protections -
-
+One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -
-
+In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -## Bridging Intent Library +## Open Source -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +Wormhole builds in the open and is always open source. -
-
+- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -🛠 **Wormhole products used:** +## Audits -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -
-
+All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +## Bug Bounties -
-
+Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -## Multichain Prediction Markets +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -
-
+For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -🛠 **Wormhole products used:** +## Learn More -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -
-
+## Install the SDK -## Cross-Chain Payment Widgets +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -
-
+## Key Components -🛠 **Wormhole products used:** +The following key components and features work together to make your on-chain Wormhole integration easier to build. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +??? interface "Base contracts" -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. +??? interface "Interfaces" -
-
+ Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -## Oracle Networks + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. +??? interface "Constants" -
-
+ Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -🛠 **Wormhole products used:** + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +## Example Usage -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -
-
+### Set Up a Project -## Cross-Chain Staking +Follow these steps to prepare your development environment: -Enable users to stake assets on one chain while earning rewards or securing networks on another. +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -
-
+ ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -🛠 **Wormhole products used:** +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -
-
---- END CONTENT --- + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -## Reference Concepts [shared: true] + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. ---- +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -## List of shared concept pages: +## Use Contracts to Transfer USDC +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -## Full content for shared concepts: + ```bash + touch script/transfer.ts + ``` -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -# Reference +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -## Get Started + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -
+ // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - --- + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } - --- + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -4001,7 +4387,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -4056,7 +4442,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -4272,262 +4658,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -4539,7 +4759,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -4714,7 +4934,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -4795,4 +5015,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-multigov.txt b/llms-files/llms-multigov.txt index 4978adc7b..1a36d0173 100644 --- a/llms-files/llms-multigov.txt +++ b/llms-files/llms-multigov.txt @@ -13,111 +13,236 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/faq.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/overview.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-evm.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-solana.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/faq.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-evm.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-solana.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov.md [type: tutorials] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov/treasury-proposal.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/tutorials/treasury-proposal.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/concepts/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-evm.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-solana.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-evm.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-solana.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/overview.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/governance/ +Doc-Content: https://wormhole.com/docs/products/multigov/tutorials/treasury-proposal/ --- BEGIN CONTENT --- --- -title: Learn about MultiGov -description: Explore the MultiGov documentation for a comprehensive guide covering architecture, deployment, upgrading, integration, and FAQs. +title: MultiGov Guides +description: Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. categories: MultiGov --- -# MultiGov +# Cross-Chain treasury management proposal -Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. Get an introduction to the core concepts, explore how the system's components work together, and find answers to common questions to help you navigate the platform effectively. +This guide walks through the process of creating and executing a cross-chain governance proposal to mint W tokens to both the Optimism and Arbitrum treasuries. In this tutorial, we'll cover how to create a proposal on the hub chain (Ethereum Mainnet), cast votes from spoke chains (Optimism and Arbitrum), aggregate votes, and execute the proposal. -## Get Started +## Create a Proposal -
+The first step is to create a proposal on the hub chain, which in this case is Ethereum Mainnet. The proposal will contain instructions to mint 10 W tokens to the Optimism treasury and 15 ETH to the Arbitrum treasury. -- :octicons-book-16:{ .lg .middle } **Overview** +In the following code snippet, we initialize the proposal with two transactions, each targeting the Hub's Message Dispatcher contract. These transactions will relay the governance actions to the respective spoke chains via Wormhole. - --- +Key actions: + +- Define the proposal targets (two transactions to the Message Dispatcher) +- Set values for each transaction (in this case, both are 0 as we're not transferring any native ETH) +- Encode the calldata for minting 10 W tokens on Optimism and sending 15 ETH to Arbitrum +- Finally, we submit the proposal to the `HubGovernor` contract + +```solidity +HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); +// Prepare proposal details +address[] memory targets = new address[](2); +targets[0] = HUB_MESSAGE_DISPATCHER_ADDRESS; +targets[1] = HUB_MESSAGE_DISPATCHER_ADDRESS; +uint256[] memory values = new uint256[](2); +values[0] = 0; +values[1] = 0; +bytes[] memory calldatas = new bytes[](2); +// Prepare message for Optimism to mint 10 W tokens +// bytes created using abi.encodeWithSignature("mint(address,uint256)", 0xB0fFa8000886e57F86dd5264b9582b2Ad87b2b91, 10e18) +calldatas[0] = abi.encodeWithSignature( + "dispatch(bytes)", + abi.encode( + OPTIMISM_WORMHOLE_CHAIN_ID, + [OPTIMISM_WORMHOLE_TREASURY_ADDRESS], + [uint256(10 ether)], + [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] + ) +); +// Prepare message for Arbitrum to receive 15 ETH +calldatas[1] = abi.encodeWithSignature( + "dispatch(bytes)", + abi.encode( + ARBITRUM_WORMHOLE_CHAIN_ID, + [ARBITRUM_WORMHOLE_TREASURY_ADDRESS], + [uint256(15 ether)], + [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] + ) +); +string memory description = "Mint 10 W to Optimism treasury and 10 W to Arbitrum treasury via Wormhole"; +// Create the proposal +uint256 proposalId = governor.propose( + targets, values, calldatas, description +) +``` + +??? interface "Parameters" - Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. + `GOVERNOR_ADDRESS` ++"address"++ + + The address of the `HubGovernor` contract on Ethereum Mainnet. + + --- - [:custom-arrow: Take a first glance at MultiGov](/docs/learn/governance/overview/) + `targets` ++"address[]"++ -- :octicons-book-16:{ .lg .middle } **Architecture** + An array that specifies the addresses that will receive the proposal's actions. Here, both are set to the `HUB_MESSAGE_DISPATCHER_ADDRESS`. --- - Discover MultiGov's hub-and-spoke architecture, enabling EVM and Solana cross-chain governance through coordinated decision-making. + `values` ++"uint256[]"++ + + An array containing the value of each transaction (in Wei). In this case, both are set to zero because no ETH is being transferred. + + --- - [:custom-arrow: Learn about MultiGov architecture](/docs/learn/governance/architecture/) + `calldatas` ++"bytes[]"++ -- :octicons-question-16:{ .lg .middle } **Theoretical FAQs** + The calldata for the proposal. These are encoded contract calls containing cross-chain dispatch instructions for minting tokens and sending ETH. The calldata specifies minting 10 W tokens to the Optimism treasury and sending 15 ETH to the Arbitrum treasury. --- - Find answers to common theoretical questions about MultiGov. + `description` ++"string"++ + + A description of the proposal, outlining the intent to mint tokens to Optimism and send ETH to Arbitrum. - [:custom-arrow: Find the answer to your theoretical questions](/docs/learn/governance/faq/) +??? interface "Returns" -
+ `proposalId` ++"uint256"++ -## Next Steps + The ID of the newly created proposal on the hub chain. -
+## Vote on the Proposal via Spoke + +Once the proposal is created on the hub chain, stakeholders can cast their votes on the spoke chains. This snippet demonstrates how to connect to a spoke chain and cast a vote for the proposal. The voting power (weight) is calculated based on each stakeholder's token holdings on the spoke chain. + +Key actions: + +- Connect to the `SpokeVoteAggregator` contract on the spoke chain. This contract aggregates votes from the spoke chains and relays them to the hub chain +- Cast a vote in support of the proposal + +```solidity +// Connect to the SpokeVoteAggregator contract of the desired chain +SpokeVoteAggregator voteAggregator = SpokeVoteAggregator(VOTE_AGGREGATOR_ADDRESS); +// Cast a vote +uint8 support = 1; // 1 for supporting, 0 for opposing +uint256 weight = voteAggregator.castVote(proposalId, support); +``` + +??? interface "Parameters" + + `VOTE_AGGREGATOR_ADDRESS` ++"address"++ + + The address of the `SpokeVoteAggregator` contract on the spoke chain (Optimism or Arbitrum). + + --- + + `proposalId` ++"uint256"++ -- :octicons-checklist-16:{ .lg .middle } **Begin the MultiGov Integration Process** + The ID of the proposal created on the hub chain, which is being voted on. --- - Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. + `support` ++"uint8"++ + + The vote being cast (`1` for supporting the proposal, `0` for opposing). + +??? interface "Returns" + + `weight` ++"uint256"++ + + The weight of the vote, determined by the voter’s token holdings on the spoke chain. + +## Vote Aggregation + +In the background process, votes cast on the spoke chains are aggregated and sent back to the hub chain for final tallying. This is typically handled off-chain by a "crank turner" service, which periodically queries the vote status and updates the hub chain. + +Key actions: + +- Aggregate votes from different chains and submit them to the hub chain for tallying + +```solidity +// Aggregate votes sent to Hub (this would typically be done by a "crank turner" off-chain) +hubVotePool.crossChainVote(queryResponseRaw, signatures); +``` + +??? interface "Parameters" - [:custom-arrow: Start the integration process now](/docs/build/multigov/) + `queryResponseRaw` ++"bytes"++ -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains** + The raw vote data from the spoke chains. --- - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. + `signatures` ++"bytes"++ + + Cryptographic signatures that verify the validity of the votes from the spoke chains. + +## Execute Proposal and Dispatch Cross-Chain Messages + +After the proposal passes and the votes are tallied, the next step is to execute the proposal. The `HubGovernor` contract will dispatch the cross-chain messages to the spoke chains, where the respective treasuries will receive the tokens. - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) +Key actions: -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +- Execute the proposal after the voting period ends and the proposal passes +- The `execute` function finalizes the proposal execution by dispatching the cross-chain governance actions. The `descriptionHash` ensures that the executed proposal matches the one that was voted on. - --- +```solidity +HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); +// Standard timelock execution +governor.execute(targets, values, calldatas, descriptionHash); +``` - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. +??? interface "Parameters" - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) + `governor` ++"HubGovernor"++ -- :octicons-code-square-16:{ .lg .middle } **Tutorials** + The `HubGovernor` contract instance. --- - Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. + `targets` ++"address[]"++ + + An array containing the target addresses for the proposal’s transactions (in this case, the `HUB_MESSAGE_DISPATCHER_ADDRESS` for both). + + --- - [:custom-arrow: Create MultiGov solutions](/docs/tutorials/multigov/) + `values` ++"uint256[]"++ -- :octicons-question-16:{ .lg .middle } **Technical FAQs** + An array of values (in Wei) associated with each transaction (both are zero in this case). --- - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. + `calldatas` ++"bytes[]"++ - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) + The encoded transaction data to dispatch the governance actions (e.g., minting tokens and transferring ETH). -
+ --- + + `descriptionHash` ++"bytes32"++ + + A hash of the proposal’s description, used to verify the proposal before execution. + +??? interface "Returns" + + No direct return, but executing this function finalizes the cross-chain governance actions by dispatching the encoded messages via Wormhole to the spoke chains. + +Once the proposal is executed, the encoded messages will be dispatched via Wormhole to the spoke chains, where the Optimism and Arbitrum treasuries will receive their respective funds. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/governance/architecture/ +Doc-Content: https://wormhole.com/docs/products/multigov/concepts/architecture/ --- BEGIN CONTENT --- --- title: MultiGov Architecture @@ -127,7 +252,13 @@ categories: MultiGov # MultiGov Architecture -MultiGov employs a hub-and-spoke model to enable cross-chain governance, utilizing Wormhole's interoperability infrastructure for secure cross-chain communication. This architecture allows coordinated decision-making across multiple blockchain networks while maintaining a central coordination point. +MultiGov uses a hub-and-spoke architecture to coordinate governance across multiple blockchains. The hub chain is the central controller that handles proposal creation, vote aggregation, and execution. Spoke chains allow token holders to vote locally and can also execute proposal outcomes specific to their network. + +Wormhole’s multichain messaging infrastructure connects the hub and spokes, enabling secure and efficient chain communication. This design allows DAOs to operate seamlessly across ecosystems while maintaining a unified governance process. + +The diagram below illustrates this high-level architecture. + +![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/products/multigov/concepts/architecture/architecture-1.webp) ## Key Components @@ -247,170 +378,164 @@ MultiGov relies on Wormhole's infrastructure for all cross-chain messaging, ensu This architecture ensures that MultiGov can operate securely and efficiently across multiple chains, allowing for truly decentralized and cross-chain governance while maintaining a unified decision-making process. -![detailed multigov architecture diagram](/docs/images/learn/governance/multigov-detailed.webp) +![detailed multigov architecture diagram](/docs/images/products/multigov/concepts/architecture/architecture-2.webp) --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/governance/faq/ +Doc-Content: https://wormhole.com/docs/products/multigov/faqs/ --- BEGIN CONTENT --- --- -title: MultiGov Theoretical FAQs +title: MultiGov FAQs description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. categories: MultiGov --- # FAQs -## General Questions - -### What is MultiGov? +## What is MultiGov? MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. It leverages Wormhole's interoperability infrastructure for seamless voting and proposal mechanisms across various chains. -### How does MultiGov differ from traditional DAO governance? +## How does MultiGov ensure security in cross-chain communication? -Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. +MultiGov leverages Wormhole's robust cross-chain communication protocol. It implements several security measures: -### What are the main components of MultiGov? +- Message origin verification to prevent unauthorized governance actions +- Timely and consistent data checks to ensure vote aggregation is based on recent and synchronized chain states +- Authorized participant validation to maintain the integrity of the governance process +- Replay attack prevention by tracking executed messages -The main components of MultiGov include: +## Can MultiGov integrate with any blockchain? -- **Hub chain** - central coordination point for governance activities -- **Spoke chains** - additional chains where token holders can participate in governance -- **Wormhole integration** - enables secure cross-chain message passing -- **Governance token** - allows holders to participate in governance across all integrated chains ---- END CONTENT --- +MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/products/reference/supported-networks/#multigov). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. -Doc-Content: https://wormhole.com/docs/learn/governance/overview/ ---- BEGIN CONTENT --- ---- -title: MultiGov Overview -description: Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. -categories: MultiGov ---- +## How are votes aggregated across different chains? -# MultiGov: Cross-Chain Governance with Wormhole +Votes are collected on each spoke chain using each chain's `SpokeVoteAggregator`. These votes are then transmitted to the HubVotePool on the hub chain for aggregation and tabulation. The `HubEvmSpokeVoteDecoder` standardizes votes from different EVM chains to ensure consistent processing. -## Overview +## Can governance upgrade from a single chain to MultiGov? -### What Is MultiGov and Why Is It Important? +Yes! MultiGov can support progressively upgrading from a single-chain governance to MultiGov. Moving to MultiGov requires upgrading the token to NTT and adding Flexible Voting to the original Governor. -MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. By leveraging Wormhole's interoperability infrastructure, MultiGov enables seamless voting and proposal mechanisms across various chains. +## How can I create a proposal in MultiGov? -MultiGov is important because it: +Proposals are created on the hub chain using the `HubEvmSpokeAggregateProposer` contract or by calling `propose` on the `HubGovernor`. You need to prepare the proposal details, including targets, values, and calldatas. The proposer's voting weight is aggregated across chains using Wormhole queries to determine eligibility. -- **Increases participation** by allowing token holders from multiple chains to engage in governance -- **Enhances security** by leveraging Wormhole's robust cross-chain communication -- **Improves scalability** by integrating any chain supported by Wormhole -- **Enables unified governance** and coordinated decision-making across multiple networks +## How do I vote on a proposal if I hold tokens on a spoke chain? -### Key Features +You can vote on proposals via the `SpokeVoteAggregator` contract on the respective spoke chain where you hold your tokens. The votes are then automatically forwarded to the hub chain for aggregation. -- **Hub and spoke model** - central coordination on a hub chain with participation from multiple spoke chains. A hub chain is where the governance state lives, while the spoke chains can be considered extensions of governance that allow for participation by token holders on other chains -- **Cross-chain voting** - token holders on any integrated chain can cast votes -- **Vote aggregation** - votes from all chains are collected and tallied on the hub -- **Cross-chain proposal execution** - approved proposals can be executed across multiple chains -- **Wormhole integration** - secure and reliable cross-chain communication -- **Flexible architecture** - can integrate with any Wormhole-supported blockchain +## How are approved proposals executed across multiple chains? -### High-Level Architecture Diagram +When a proposal is approved and the timelock period elapses, it's first executed on the hub chain. A proposal can include a cross-chain message by including a call to `dispatch` on the `HubMessageDispatcher`, which sends a message to the relevant spoke chains. On each spoke chain, the `SpokeMessageExecutor` receives, verifies, and automatically executes the instructions using the `SpokeAirlock` as the `msg.sender`. -The diagram below represents MultiGov's high-level architecture, focusing on its hub-and-spoke model for decentralized governance across multiple chains. The hub chain acts as the central governance controller, managing proposal creation, vote tallying, and execution, while the spoke chains handle local voting and proposal execution on individual chains. The hub and spoke chains communicate via Wormhole's cross-chain messaging infrastructure, ensuring secure and efficient governance across multiple blockchain networks. +## What are the requirements for using MultiGov? -For a deeper understanding of the system's structure and how the components interact, refer to the [MultiGov Architecture](/docs/learn/governance/architecture/){target=\_blank} page. +To use MultiGov, your DAO must meet the following requirements: - -![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/learn/governance/multigov-high-level.webp) ---- END CONTENT --- +- **ERC20Votes token** - your DAO's token must implement the `ERC20Votes` standard and support `CLOCK_MODE` timestamps for compatibility with cross-chain governance +- **Flexible voting support** - your DAO's Governor must support Flexible Voting to function as the Hub Governor. If your existing Governor does not support Flexible Voting, you can upgrade it to enable this feature -Doc-Content: https://wormhole.com/docs/build/multigov/ ---- BEGIN CONTENT --- ---- -title: Getting Started with MultiGov -description: Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. -categories: MultiGov ---- +## What do I need to set up MultiGov for my project? -# MultiGov +Get started by filling out the form below: -## Begin the MultiGov Integration Process +https://www.tally.xyz/get-started -Take the following steps to get started with a MultiGov integration: +Tally will reach out to help get your DAO set up with MultiGov. -1. Evaluate if [MultiGov](/docs/learn/governance/) meets your cross-chain governance needs -2. Fill out the intake form on the [Tally website](https://www.tally.xyz/get-started){target=\_blank} -3. The Tally team will review your application and contact you to discuss implementation details -4. Work with the Tally team to customize and deploy MultiGov for your specific use case +To set up testing MultiGov for your DAO, you'll need: -## Start Building +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} and [Git](https://git-scm.com/downloads){target=\_blank} installed +- Test ETH on the testnets you plan to use (e.g., Sepolia for hub, Optimism Sepolia for spoke) +- Modify and deploy the hub and spoke contracts using the provided scripts +- Set up the necessary environment variables and configurations -
+## Can MultiGov be used with non-EVM chains? -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** +The current implementation is designed for EVM-compatible chains. However, Solana (non-EVM) voting is currently in development and expected to go live after the EVM contracts. - --- +## How can I customize voting parameters in MultiGov? - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. +Voting parameters such as voting delay, voting period, proposal threshold, and quorum (and others) can be customized in the deployment scripts (`DeployHubContractsSepolia.s.sol` and `DeploySpokeContractsOptimismSepolia.s.sol` as examples for their respective chains). Make sure to adjust these parameters according to your DAO's specific needs before deployment. - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) +Remember to thoroughly test your MultiGov implementation on testnets before deploying to Mainnet, and have your contracts audited for additional security. -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +## How does MultiGov handle potential network issues or temporary chain unavailability? - --- +MultiGov includes several mechanisms to handle network issues or temporary chain unavailability: - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. +1. **Asynchronous vote aggregation** - votes are aggregated periodically, allowing the system to continue functioning even if one chain is temporarily unavailable +2. **Proposal extension** - the `HubGovernorProposalExtender` allows trusted actors to extend voting periods if needed, which can help mitigate issues caused by temporary network problems +3. **Wormhole retry mechanism** - Wormhole's infrastructure includes retry mechanisms for failed message deliveries, helping ensure cross-chain messages eventually get through +4. **Decentralized relayer network** - Wormhole's decentralized network of relayers helps maintain system availability even if some relayers are offline - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) +However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on EVM Chains** +## How does MultiGov differ from traditional DAO governance? - --- +Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. - Learn the process and key considerations for upgrading MultiGov contracts, ensuring system integrity and careful planning across cross-chain components. +## What are the main components of MultiGov? - [:custom-arrow: Discover how to upgrade MultiGov on EVM Chains](/docs/build/multigov/upgrade-evm/) +The main components of MultiGov include: -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on Solana** +- **Hub chain** - central coordination point for governance activities +- **Spoke chains** - additional chains where token holders can participate in governance +- **Wormhole integration** - enables secure cross-chain message passing +- **Governance token** - allows holders to participate in governance across all integrated chains +--- END CONTENT --- - --- +Doc-Content: https://wormhole.com/docs/products/multigov/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Multigov +description: Follow this guide to set up your environment and request access to deploy MultiGov contracts for multichain DAO governance using Wormhole messaging. +categories: MultiGov +--- - Learn how to upgrade the MultiGov Staking Program on Solana, including updating the program binary, IDL, and more. +# Get Started with Multigov - [:custom-arrow: Discover how to upgrade MultiGov on Solana](/docs/build/multigov/upgrade-solana/) +## Introduction -- :octicons-question-16:{ .lg .middle } **Technical FAQs** +[MultiGov](/docs/products/multigov/overview/){target=\_blank} enables multichain governance using Wormhole messaging. With MultiGov, token holders can create proposals, vote, and execute decisions from any supported chain, eliminating the need to bridge assets or rely on a single governance hub. - --- +This page walks you through the MultiGov deployment flow—from requesting access with Tally to choosing a network and following the appropriate deployment guide. - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. +## Prerequisites - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) +Before deploying MultiGov, you need a governance token deployed on multiple chains (ERC-20 or SPL): -
+- **EVM chains**: + - Your token must implement the [`ERC20Votes`](https://docs.openzeppelin.com/contracts/4.x/governance#erc20votes){target=\_blank} standard + - It must support `CLOCK_MODE` timestamps for compatibility with cross-chain voting -## Additional Resources +- **Solana**: + - Use an SPL token + - Voting eligibility and weight are managed by the [MultiGov staking program](/docs/products/multigov/concepts/architecture/#spoke-solana-staking-program){target=\_blank} -
+## Request Tally Access -- :octicons-book-16:{ .lg .middle } **What is MultiGov?** +MultiGov integrations are coordinated through [Tally](https://www.tally.xyz/explore){target=\_blank}, a multichain governance platform that powers proposal creation, voting, and execution. - --- +To get started, fill out the integration [intake form](https://www.tally.xyz/get-started){target=\_blank}. The Tally team will review your application and contact you to discuss deployment and setup requirements. - Need to familiarize yourself with MultiGov? Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. +Once approved, review the deployment flow below to understand the integration process. Then, follow the appropriate deployment guide to integrate MultiGov with your governance token on EVM chains, Solana, or other supported networks. - [:custom-arrow: Learn the basics](/docs/learn/governance/) +## Deployment Flow -- :octicons-checklist-16:{ .lg .middle } **Tutorials** +MultiGov deployments follow a similar structure on both EVM and Solana. This section provides a high-level overview of the end-to-end flow. Each step is explained in more detail in the platform-specific deployment guides linked [below](#next-steps). - --- +[timeline(wormhole-docs/.snippets/text/products/multigov/deployment-flow-timeline.json)] - Access step-by-step tutorials for executing cross-chain governance actions, including treasury management proposals with MultiGov. +## Next Steps - [:custom-arrow: Learn by building](/docs/tutorials/multigov/) +You've now completed the initial setup and requested access through Tally. Continue to the deployment guide that matches your governance architecture: -
+ - [**Deploy on EVM Chains**](/docs/products/multigov/guides/deploy-to-evm){target=\_blank}: Configure and deploy MultiGov smart contracts to EVM-compatible chains. + - [**Deploy on Solana**](/docs/products/multigov/guides/deploy-to-solana){target=\_blank}: Launch the Solana staking program and configure spoke chain participation. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/deploy-to-evm/ +Doc-Content: https://wormhole.com/docs/products/multigov/guides/deploy-to-evm/ --- BEGIN CONTENT --- --- title: Deploy MultiGov on EVM Chains @@ -420,7 +545,7 @@ categories: MultiGov # Deploy MultiGov on EVM Chains -This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/build/multigov/){target=\_blank}. +This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/products/multigov/get-started/){target=\_blank}. Once your project is approved through the intake process and you’ve collaborated with the Tally team to tailor MultiGov to your requirements, use this guide to configure, compile, and deploy the necessary smart contracts across your desired blockchain networks. This deployment will enable decentralized governance across your hub and spoke chains. @@ -516,7 +641,7 @@ These parameters can be queried using their respective getter functions on the a To update these parameters, a governance proposal must be created, voted on, and executed through the standard MultiGov process. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/deploy-to-solana/ +Doc-Content: https://wormhole.com/docs/products/multigov/guides/deploy-to-solana/ --- BEGIN CONTENT --- --- title: MultiGov Deployment to Solana @@ -526,7 +651,7 @@ categories: MultiGov # Deploy MultiGov on Solana -This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/learn/governance/architecture/){target=\_blank}. +This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/products/multigov/concepts/architecture/){target=\_blank}. Once your project setup is complete, follow this guide to configure, compile, and deploy the necessary Solana programs and supporting accounts. This deployment enables decentralized governance participation on Solana as a spoke chain within the MultiGov system. @@ -706,112 +831,19 @@ When deploying MultiGov on Solana, several key parameters need to be set. Here a - `hubDispatcher` ++"Pubkey"++ - the Solana public key derived from an Ethereum address on the hub chain that dispatches messages to the spoke chains. This is crucial for ensuring that only authorized messages from the hub are executed on the spoke --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/faq/ +Doc-Content: https://wormhole.com/docs/products/multigov/guides/upgrade-evm/ --- BEGIN CONTENT --- --- -title: MultiGov Technical FAQs -description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. +title: Upgrading MultiGov on EVM +description: Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. categories: MultiGov --- -# FAQs +# Upgrade MultiGov Contracts on EVM Chains -## Technical Questions +MultiGov is designed to be flexible but stable. Due to the system's complexity and cross-chain nature, upgrades should be rare and carefully considered. When upgrades are necessary, they must be meticulously planned and executed to ensure system integrity and continuity. -### How does MultiGov ensure security in cross-chain communication? - -MultiGov leverages Wormhole's robust cross-chain communication protocol. It implements several security measures: - -- Message origin verification to prevent unauthorized governance actions -- Timely and consistent data checks to ensure vote aggregation is based on recent and synchronized chain states -- Authorized participant validation to maintain the integrity of the governance process -- Replay attack prevention by tracking executed messages - -### Can MultiGov integrate with any blockchain? - -MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/build/start-building/supported-networks/). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. - -### How are votes aggregated across different chains? - -Votes are collected on each spoke chain using each chain's `SpokeVoteAggregator`. These votes are then transmitted to the HubVotePool on the hub chain for aggregation and tabulation. The `HubEvmSpokeVoteDecoder` standardizes votes from different EVM chains to ensure consistent processing. - -### Can governance upgrade from a single chain to MultiGov? - -Yes! MultiGov can support progressively upgrading from a single-chain governance to MultiGov. Moving to MultiGov requires upgrading the token to NTT and adding Flexible Voting to the original Governor. - -## Usage Questions - -### How can I create a proposal in MultiGov? - -Proposals are created on the hub chain using the `HubEvmSpokeAggregateProposer` contract or by calling `propose` on the `HubGovernor`. You need to prepare the proposal details, including targets, values, and calldatas. The proposer's voting weight is aggregated across chains using Wormhole queries to determine eligibility. - -### How do I vote on a proposal if I hold tokens on a spoke chain? - -You can vote on proposals via the `SpokeVoteAggregator` contract on the respective spoke chain where you hold your tokens. The votes are then automatically forwarded to the hub chain for aggregation. - -### How are approved proposals executed across multiple chains? - -When a proposal is approved and the timelock period elapses, it's first executed on the hub chain. A proposal can include a cross-chain message by including a call to `dispatch` on the `HubMessageDispatcher`, which sends a message to the relevant spoke chains. On each spoke chain, the `SpokeMessageExecutor` receives, verifies, and automatically executes the instructions using the `SpokeAirlock` as the `msg.sender`. - -## Implementation Questions - -### What are the requirements for using MultiGov? - -To use MultiGov, your DAO must meet the following requirements: - -- **ERC20Votes token** - your DAO's token must implement the `ERC20Votes` standard and support `CLOCK_MODE` timestamps for compatibility with cross-chain governance -- **Flexible voting support** - your DAO's Governor must support Flexible Voting to function as the Hub Governor. If your existing Governor does not support Flexible Voting, you can upgrade it to enable this feature - -### What do I need to set up MultiGov for my project? - -Get started by filling out the form below: - -https://www.tally.xyz/get-started - -Tally will reach out to help get your DAO set up with MultiGov. - -To set up testing MultiGov for your DAO, you'll need: - -- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} and [Git](https://git-scm.com/downloads){target=\_blank} installed -- Test ETH on the testnets you plan to use (e.g., Sepolia for hub, Optimism Sepolia for spoke) -- Modify and deploy the hub and spoke contracts using the provided scripts -- Set up the necessary environment variables and configurations - -### Can MultiGov be used with non-EVM chains? - -The current implementation is designed for EVM-compatible chains. However, Solana (non-EVM) voting is currently in development and expected to go live after the EVM contracts. - -### How can I customize voting parameters in MultiGov? - -Voting parameters such as voting delay, voting period, proposal threshold, and quorum (and others) can be customized in the deployment scripts (`DeployHubContractsSepolia.s.sol` and `DeploySpokeContractsOptimismSepolia.s.sol` as examples for their respective chains). Make sure to adjust these parameters according to your DAO's specific needs before deployment. - -Remember to thoroughly test your MultiGov implementation on testnets before deploying to Mainnet, and have your contracts audited for additional security. - -### How does MultiGov handle potential network issues or temporary chain unavailability? - -MultiGov includes several mechanisms to handle network issues or temporary chain unavailability: - -1. **Asynchronous vote aggregation** - votes are aggregated periodically, allowing the system to continue functioning even if one chain is temporarily unavailable -2. **Proposal extension** - the `HubGovernorProposalExtender` allows trusted actors to extend voting periods if needed, which can help mitigate issues caused by temporary network problems -3. **Wormhole retry mechanism** - Wormhole's infrastructure includes retry mechanisms for failed message deliveries, helping ensure cross-chain messages eventually get through -4. **Decentralized relayer network** - Wormhole's decentralized network of relayers helps maintain system availability even if some relayers are offline - -However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/multigov/upgrade-evm/ ---- BEGIN CONTENT --- ---- -title: Upgrading MultiGov on EVM -description: Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. -categories: MultiGov ---- - -# Upgrade MultiGov Contracts on EVM Chains - -MultiGov is designed to be flexible but stable. Due to the system's complexity and cross-chain nature, upgrades should be rare and carefully considered. When upgrades are necessary, they must be meticulously planned and executed to ensure system integrity and continuity. - -## Key Considerations for Upgrades +## Key Considerations for Upgrades - **`HubGovernor`**: - Not upgradeable. A new deployment requires redeploying several components of the MultiGov system. Refer to the [Process for Major System Upgrade](#process-for-major-system-upgrade) section for more details @@ -869,7 +901,7 @@ MultiGov is designed to be flexible but stable. Due to the system's complexity a - Always test upgrades extensively on testnets before implementing in production --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/upgrade-solana/ +Doc-Content: https://wormhole.com/docs/products/multigov/guides/upgrade-solana/ --- BEGIN CONTENT --- --- title: Upgrading MultiGov on Solana @@ -940,2371 +972,2559 @@ Follow these steps to upgrade the MultiGov Staking Program on Solana: ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/multigov/ +Doc-Content: https://wormhole.com/docs/products/multigov/overview/ --- BEGIN CONTENT --- --- -title: Step-by-Step MultiGov Tutorials -description: Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. -categories: MultiGov +title: MultiGov Overview +description: Enable multichain governance with MultiGov. Create, vote, and execute DAO proposals securely across Wormhole supported networks. +categories: Multigov --- -# MultiGov +# MultiGov Overview + +MultiGov is a multichain governance system that enables decentralized decision-making across multiple blockchain networks. Built on Wormhole messaging, it allows DAOs to manage proposals, voting, and execution from any connected chain without relying on a single hub or bridging assets. It empowers true multichain governance by aggregating voting power across chains and coordinating secure proposal execution. -Welcome to the MultiGov tutorials section. In this section, you will find tutorials that walk you through the key steps of working with MultiGov, providing clear instructions to help you get started. As you explore, you'll gain a deeper understanding of MultiGov's features and functionality. +## Key Features -## Tutorials +MultiGov expands DAO governance across blockchains, increasing participation, improving security with Wormhole messaging, and enabling unified decision-making at scale. Key features include: -
+- **Multichain governance**: Token holders can vote and execute proposals from any supported chain. +- **Hub-and-spoke model**: Proposals are created on a central hub chain and voted on from spoke chains, where governance tokens live. +- **Secure vote aggregation**: Vote weights are checkpointed and verified to prevent double voting. +- **Cross-chain proposal execution**: Approved proposals can be executed across multiple chains. +- **Flexible architecture**: Can integrate with any Wormhole-supported blockchain. +- **Upgradeable and extensible**: Supports upgrades across components while preserving vote history and system continuity. +- **Backed by Tally**: Proposal creation, voting, and execution are coordinated via [Tally](https://www.tally.xyz/get-started){target=\_blank}. -- :octicons-repo-16:{ .lg .middle } **Cross-Chain Treasury Management Proposal** +## How It Works - --- +1. **Create proposal on hub chain**: Proposals are created on the hub chain, which manages the core governance logic, including vote aggregation and execution scheduling. +2. **Vote from spoke chains**: Token holders on spoke chains vote locally using `SpokeVoteAggregators`, with checkpoints tracking their voting power. +3. **Transmit votes via Wormhole**: Votes are securely sent to the hub using [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}, ensuring message integrity and cross-chain verification. +4. **Aggregate and finalize on hub**: The hub chain receives votes from all spokes, tallies results, and finalizes the outcome once the voting period ends. +5. **Execute actions across chains**: Upon approval, proposals can trigger execution on one or more chains, again using [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} to deliver commands. - Learn how to propose governance actions on a hub chain, gather votes from spoke chains, aggregate the results, and carry out the final decision. Following these steps, you’ll master end-to-end governance workflows spanning multiple networks. + - [:custom-arrow: Start building](/docs/tutorials/multigov/treasury-proposal/) +## Use Cases -
+- **Cross-Chain Treasury Management** -## Additional Resources + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Vote on treasury actions from any supported chain. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Transmit proposal execution to target chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Optionally move assets. -
+- **Coordinated Protocol Upgrades Across Chains** -- :octicons-book-16:{ .lg .middle } **Governance Fundamentals** + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Create a unified proposal to upgrade contracts across networks. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Send upgrade instructions as VAAs and deliver execution payloads to target chains. + +- **Progressive Decentralization for Multichain DAOs** - --- + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Extend governance to new chains while preserving coordination. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch on-chain vote weights from remote spokes. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Aggregate results and execute actions via the hub. - Dive into Wormhole’s governance mechanisms. Understand how cross-chain governance works, proposal creation, voting, and execution. +## Next Steps - [:custom-arrow: Explore governance](/docs/learn/governance/) +Follow these steps to get started with MultiGov: -- :octicons-tools-16:{ .lg .middle } **Implement MultiGov** +[timeline(wormhole-docs/.snippets/text/products/multigov/multigov-timeline.json)] +--- END CONTENT --- - --- +## Basics Concepts [shared: true] + +The following section contains foundational documentation shared across all Wormhole products. +It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. +This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. +This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. - Integrate MultiGov into your smart contracts. Access reference code, best practices, and guidance for deploying cross-chain governance systems. +--- +## List of shared concept pages: - [:custom-arrow: Build with MultiGov](/docs/build/multigov/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/tutorials/multigov/treasury-proposal/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: MultiGov Guides -description: Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. -categories: MultiGov +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Cross-Chain treasury management proposal +# Get Started with Messaging -This guide walks through the process of creating and executing a cross-chain governance proposal to mint W tokens to both the Optimism and Arbitrum treasuries. In this tutorial, we'll cover how to create a proposal on the hub chain (Ethereum Mainnet), cast votes from spoke chains (Optimism and Arbitrum), aggregate votes, and execute the proposal. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Create a Proposal +## Prerequisites -The first step is to create a proposal on the hub chain, which in this case is Ethereum Mainnet. The proposal will contain instructions to mint 10 W tokens to the Optimism treasury and 15 ETH to the Arbitrum treasury. +Before you begin, ensure you have the following: -In the following code snippet, we initialize the proposal with two transactions, each targeting the Hub's Message Dispatcher contract. These transactions will relay the governance actions to the respective spoke chains via Wormhole. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -Key actions: +## Configure Your Messaging Environment -- Define the proposal targets (two transactions to the Message Dispatcher) -- Set values for each transaction (in this case, both are 0 as we're not transferring any native ETH) -- Encode the calldata for minting 10 W tokens on Optimism and sending 15 ETH to Arbitrum -- Finally, we submit the proposal to the `HubGovernor` contract +1. Create a directory and initialize a Node.js project: -```solidity -HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); -// Prepare proposal details -address[] memory targets = new address[](2); -targets[0] = HUB_MESSAGE_DISPATCHER_ADDRESS; -targets[1] = HUB_MESSAGE_DISPATCHER_ADDRESS; -uint256[] memory values = new uint256[](2); -values[0] = 0; -values[1] = 0; -bytes[] memory calldatas = new bytes[](2); -// Prepare message for Optimism to mint 10 W tokens -// bytes created using abi.encodeWithSignature("mint(address,uint256)", 0xB0fFa8000886e57F86dd5264b9582b2Ad87b2b91, 10e18) -calldatas[0] = abi.encodeWithSignature( - "dispatch(bytes)", - abi.encode( - OPTIMISM_WORMHOLE_CHAIN_ID, - [OPTIMISM_WORMHOLE_TREASURY_ADDRESS], - [uint256(10 ether)], - [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] - ) -); -// Prepare message for Arbitrum to receive 15 ETH -calldatas[1] = abi.encodeWithSignature( - "dispatch(bytes)", - abi.encode( - ARBITRUM_WORMHOLE_CHAIN_ID, - [ARBITRUM_WORMHOLE_TREASURY_ADDRESS], - [uint256(15 ether)], - [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] - ) -); -string memory description = "Mint 10 W to Optimism treasury and 10 W to Arbitrum treasury via Wormhole"; -// Create the proposal -uint256 proposalId = governor.propose( - targets, values, calldatas, description -) -``` + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -??? interface "Parameters" +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: - `GOVERNOR_ADDRESS` ++"address"++ + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` - The address of the `HubGovernor` contract on Ethereum Mainnet. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: - --- + ```bash + npx tsc --init + ``` - `targets` ++"address[]"++ + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` - An array that specifies the addresses that will receive the proposal's actions. Here, both are set to the `HUB_MESSAGE_DISPATCHER_ADDRESS`. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: - --- + ```bash + npm install @wormhole-foundation/sdk + ``` - `values` ++"uint256[]"++ +5. Create a new file named `main.ts`: - An array containing the value of each transaction (in Wei). In this case, both are set to zero because no ETH is being transferred. + ```bash + touch main.ts + ``` - --- +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } - `calldatas` ++"bytes[]"++ + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); - The calldata for the proposal. These are encoded contract calls containing cross-chain dispatch instructions for minting tokens and sending ETH. The calldata specifies minting 10 W tokens to the Optimism treasury and sending 15 ETH to the Arbitrum treasury. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); - --- + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; - `description` ++"string"++ + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); - A description of the proposal, outlining the intent to mint tokens to Optimism and send ETH to Arbitrum. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -??? interface "Returns" + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} - `proposalId` ++"uint256"++ +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` - The ID of the newly created proposal on the hub chain. + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -## Vote on the Proposal via Spoke +2. Run the script using the following command: -Once the proposal is created on the hub chain, stakeholders can cast their votes on the spoke chains. This snippet demonstrates how to connect to a spoke chain and cast a vote for the proposal. The voting power (weight) is calculated based on each stakeholder's token holdings on the spoke chain. + ```bash + npx tsx main.ts + ``` -Key actions: + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-- Connect to the `SpokeVoteAggregator` contract on the spoke chain. This contract aggregates votes from the spoke chains and relays them to the hub chain -- Cast a vote in support of the proposal +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -```solidity -// Connect to the SpokeVoteAggregator contract of the desired chain -SpokeVoteAggregator voteAggregator = SpokeVoteAggregator(VOTE_AGGREGATOR_ADDRESS); -// Cast a vote -uint8 support = 1; // 1 for supporting, 0 for opposing -uint256 weight = voteAggregator.castVote(proposalId, support); -``` +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -??? interface "Parameters" +## Next Steps - `VOTE_AGGREGATOR_ADDRESS` ++"address"++ +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- - The address of the `SpokeVoteAggregator` contract on the spoke chain (Optimism or Arbitrum). +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +categories: Basics +--- - --- +# Get Started with Core Contracts - `proposalId` ++"uint256"++ +## Introduction - The ID of the proposal created on the hub chain, which is being voted on. +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. - --- +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - `support` ++"uint8"++ +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. - The vote being cast (`1` for supporting the proposal, `0` for opposing). +## Prerequisites -??? interface "Returns" +To interact with the Wormhole Core Contract, you'll need the following: - `weight` ++"uint256"++ +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - The weight of the vote, determined by the voter’s token holdings on the spoke chain. +## How to Interact with Core Contracts -## Vote Aggregation +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -In the background process, votes cast on the spoke chains are aggregated and sent back to the hub chain for final tallying. This is typically handled off-chain by a "crank turner" service, which periodically queries the vote status and updates the hub chain. +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -Key actions: +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -- Aggregate votes from different chains and submit them to the hub chain for tallying +### Sending Messages -```solidity -// Aggregate votes sent to Hub (this would typically be done by a "crank turner" off-chain) -hubVotePool.crossChainVote(queryResponseRaw, signatures); -``` +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -??? interface "Parameters" - - `queryResponseRaw` ++"bytes"++ - - The raw vote data from the spoke chains. - - --- - - `signatures` ++"bytes"++ - - Cryptographic signatures that verify the validity of the votes from the spoke chains. - -## Execute Proposal and Dispatch Cross-Chain Messages - -After the proposal passes and the votes are tallied, the next step is to execute the proposal. The `HubGovernor` contract will dispatch the cross-chain messages to the spoke chains, where the respective treasuries will receive the tokens. - -Key actions: - -- Execute the proposal after the voting period ends and the proposal passes -- The `execute` function finalizes the proposal execution by dispatching the cross-chain governance actions. The `descriptionHash` ensures that the executed proposal matches the one that was voted on. - -```solidity -HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); -// Standard timelock execution -governor.execute(targets, values, calldatas, descriptionHash); -``` - -??? interface "Parameters" - - `governor` ++"HubGovernor"++ - - The `HubGovernor` contract instance. - - --- - - `targets` ++"address[]"++ - - An array containing the target addresses for the proposal’s transactions (in this case, the `HUB_MESSAGE_DISPATCHER_ADDRESS` for both). - - --- - - `values` ++"uint256[]"++ - - An array of values (in Wei) associated with each transaction (both are zero in this case). - - --- - - `calldatas` ++"bytes[]"++ - - The encoded transaction data to dispatch the governance actions (e.g., minting tokens and transferring ETH). - - --- - - `descriptionHash` ++"bytes32"++ - - A hash of the proposal’s description, used to verify the proposal before execution. - -??? interface "Returns" - - No direct return, but executing this function finalizes the cross-chain governance actions by dispatching the encoded messages via Wormhole to the spoke chains. - -Once the proposal is executed, the encoded messages will be dispatched via Wormhole to the spoke chains, where the Optimism and Arbitrum treasuries will receive their respective funds. ---- END CONTENT --- - -## Basics Concepts [shared: true] - -The following section contains foundational documentation shared across all Wormhole products. -It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. -This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. -This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. - ---- - -## List of shared concept pages: - - -## Full content for shared concepts: - -Doc-Content: https://wormhole.com/docs/learn/glossary/ ---- BEGIN CONTENT --- ---- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics ---- - -# Glossary - -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - -## Chain ID - -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. - -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. - -## Consistency Level - -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. - -## Delivery Provider - -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. - -## Emitter - -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - -## Finality - -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - -## Guardian - -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - -## Guardian Network - -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. - -## Guardian Set - -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - -## Heartbeat - -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. - -## Observation - -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. - -## Relayer - -A relayer is any process that delivers VAAs to a destination. - -## Sequence - -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - -## Spy - -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - -## VAA - -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - -## Validator - -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ ---- BEGIN CONTENT --- ---- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics ---- - -# Infrastructure Components - -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. - -## Get Started - -Start here for an overview of Wormhole architecture components and security mechanisms: - -
- -- :octicons-book-16:{ .lg .middle } **Architecture Overview** - - --- - - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. - - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) - -- :octicons-book-16:{ .lg .middle } **Security** - - --- - - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. - - [:custom-arrow: Learn About Security](/docs/learn/security/) - -
- -## Explore Components - -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: - -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] - -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. - -## Next Steps - -
- -- :octicons-book-16:{ .lg .middle } **Messaging Components** - - --- - - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) - -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** - - --- - - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. - - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- - -# Architecture - -## Overview - -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. - -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) - -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: - -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract - -## On-Chain Components - -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract - -## Off-Chain Components - -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers - -## Next Steps - -
- -- :octicons-book-16:{ .lg .middle } **Core Contracts** - - --- - - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) - -- :octicons-tools-16:{ .lg .middle } **Core Messaging** - - --- - - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. - - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- - -# Core Contracts - -## Introduction - -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. - -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. - -## Key Functions - -Key functions of the Wormhole Core Contract include the following: - -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time - -## How the Core Contract Works - -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. - -The following describes the role of the Wormhole Core Contract in message transfers: - -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions - -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. - -### Message Submission - -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: +=== "EVM" -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -### Message Reception + ??? interface "Parameters" -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -## Multicast + --- -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + --- -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + ??? interface "Returns" -## Next Steps + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -
+ ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - --- +// Check fee and send parameters - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` - --- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. +=== "Solana" - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -
---- END CONTENT --- + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Parameters" -## Guardian + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -Guardians fulfill their role in the messaging protocol as follows: + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). + ??? child "Type `PostMessage<'info>`" -## Guardian Network + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -The Guardian Network is designed to help Wormhole deliver on five key principles: + --- -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing + `batch_id` ++"u32"++ + + An identifier for the message batch. -The following sections explore each principle in detail. + --- -### Decentralization + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. + --- -Two common approaches to decentralization have notable limitations: + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -To answer that, consider these key constraints and design decisions: +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -### Modularity +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -### Chain Agnosticism +### Receiving Messages -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +The way a message is received and handled depends on the environment. -### Scalability +=== "EVM" -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. + ??? interface "Parameters" -### Upgradeable + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -Wormhole is designed to adapt and evolve in the following ways: + ??? interface "Returns" -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + ??? child "Struct `VM`" -## Next Steps + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -
+ For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -- :octicons-book-16:{ .lg .middle } **Relayers** + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- - --- + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. + ??? interface "Example" - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + // Perform safety checks here - --- + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + // Your custom application logic here +} + ``` - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -
---- END CONTENT --- +=== "Solana" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -# Relayers + Retrieve the raw message data: -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. + ??? interface "Example" -There are three primary types of relayers discussed: + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +#### Validating the Emitter -## Fundamentals +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -Key characteristics of VAAs include: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- Public emission from the Guardian Network +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -- Authentication through signatures from the Guardian Network +await tx.wait(); +``` -- Verifiability by any entity or any Wormhole Core Contract +#### Additional Checks -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Keep in mind the following security considerations around relayers: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +## Source Code References -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -## Client-Side Relaying +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -### Key Features +# Wormhole Relayer -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +## Introduction -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -### Implementation +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -Users themselves carry out the three steps of the cross-chain process: +## Get Started with the Wormhole Relayer -1. Perform an action on chain A +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -2. Retrieve the resulting VAA from the Guardian Network +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -3. Perform an action on chain B using the VAA +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-### Considerations +### Wormhole Relayer Interfaces -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -- Users must sign all required transactions with their own wallet +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- Users must have funds to pay the transaction fees on every chain involved +## Interact with the Wormhole Relayer -- The user experience may be cumbersome due to the manual steps involved +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -## Custom Relayers +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +Your initial set up should resemble the following: -### Key Features +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +contract Example { + IWormholeRelayer public wormholeRelayer; -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -### Implementation +### Send a Message -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -### Considerations +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -- Development work and hosting of relayers are required +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -## Wormhole Relayers +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -### Key Features +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +### Receive a Message -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -### Implementation +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -The Wormhole relayer integration involves two key steps: +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +## Delivery Guarantees -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -### Considerations +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -- All computations are performed on-chain +## Delivery Statuses -- Potentially less gas-efficient compared to custom relayers +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- Support may not be available for all chains +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -## Next Steps +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -
+All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -- :octicons-book-16:{ .lg .middle } **Spy** +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. - --- +## Other Considerations - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +## Track the Progress of Messages with the Wormhole CLI - --- +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +=== "Mainnet" - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +=== "Testnet" - --- + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Step-by-Step Tutorial -
+For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. categories: Basics --- -# Spy - -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +# Messaging Overview -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. ## Key Features -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -## Integrator Use Case +## How It Works -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +The messaging flow consists of several core components: -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -## Observable Message Categories +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -A Spy can access the following categories of messages shared over the gossip protocol: +## Use Cases -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +- **Gas Abstraction** -## Additional Resources + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -
+- **Bridging Intent Library** -- :octicons-code-16:{ .lg .middle } **Spy Source Code** + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. - --- +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +## Next Steps -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +Follow these steps to work with Wormhole Messaging: - --- +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +# Products -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. - --- +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +## Transfer Products -
+Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -## Next Steps +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-- :octicons-code-16:{ .lg .middle } **Run a Spy** +::spantable:: - --- +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +::end-spantable:: - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +
-- :octicons-code-16:{ .lg .middle } **Use Queries** +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - --- +
- For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. + +## Bridging UI - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. -
+## Real-time Data + +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + +## Multichain Governance + +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Glossary -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +## Chain ID -## VAA Format +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -The basic VAA consists of header and body components described as follows: +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +## Consistency Level - Where each `signature` is: +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +## Delivery Provider -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +## Emitter -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +## Finality -## Consistency and Finality +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +## Guardian -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -## Signatures +## Guardian Network -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` +## Guardian Set -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -## Payload Types +## Heartbeat -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. -### Token Transfer +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +## Observation -Transferring tokens from the sending chain to the destination chain requires the following steps: +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +## Relayer -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +A relayer is any process that delivers VAAs to a destination. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +## Sequence -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Spy -### Attestation +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +## VAA -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -The message format for token attestation is as follows: +## Validator -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- -#### Attestation Tips +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- -Be aware of the following considerations when working with attestations: +# Architecture -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +## Overview -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. -### Token Transfer with Message + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +## On-Chain Components -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## Off-Chain Components -### Governance +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +## Next Steps -#### Action Structure +
-Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +- :octicons-book-16:{ .lg .middle } **Core Contracts** -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action + --- -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -#### Actions +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: + --- -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -## Lifetime of a Message + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +
+--- END CONTENT --- -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +# The Wormhole Ecosystem -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -## Next Steps +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-book-16:{ .lg .middle } **Guardians** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. categories: Basics --- -# Introduction to Wormhole +# Core Contracts -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +## Introduction -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +## Key Functions -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +Key functions of the Wormhole Core Contract include the following: -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## How the Core Contract Works -## What Problems Does Wormhole Solve? +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following describes the role of the Wormhole Core Contract in message transfers: -Critical problems Wormhole addresses include: +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -## What Does Wormhole Offer? +### Message Submission -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -## What Isn't Wormhole? +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +### Message Reception -## Use Cases of Wormhole +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -Consider the following examples of potential applications enabled by Wormhole: +## Multicast -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -## Explore +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -Discover more about the Wormhole ecosystem, components, and protocols: +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -## Demos +## Next Steps -Demos offer more realistic implementations than tutorials: +
-- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** - + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -!!! note - Wormhole Integration Complete? + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** + --- -## Supported Blockchains + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -Wormhole supports a growing number of blockchains. + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Security +## Guardian -## Core Security Assumptions +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Guardians fulfill their role in the messaging protocol as follows: -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -In summary: +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +## Guardian Network -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## Guardian Network +The Guardian Network is designed to help Wormhole deliver on five key principles: -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Governance +The following sections explore each principle in detail. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +### Decentralization -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +Two common approaches to decentralization have notable limitations: -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -Via governance, the Guardians can: +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +To answer that, consider these key constraints and design decisions: -## Monitoring +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +### Modularity -Guardians monitor: +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Chain Agnosticism -## Asset Layer Protections +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +### Scalability -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -## Open Source +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -Wormhole builds in the open and is always open source. +### Upgradeable -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +Wormhole is designed to adapt and evolve in the following ways: -## Audits +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +## Next Steps -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +
-## Bug Bounties +- :octicons-book-16:{ .lg .middle } **Relayers** -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + --- -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -## Learn More + --- -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Get Started with Core Contracts +# Relayers -## Introduction +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +There are three primary types of relayers discussed: -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -## Prerequisites +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -To interact with the Wormhole Core Contract, you'll need the following: +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +## Fundamentals -## How to Interact with Core Contracts +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +Key characteristics of VAAs include: -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- Public emission from the Guardian Network -### Sending Messages +- Authentication through signatures from the Guardian Network -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +- Verifiability by any entity or any Wormhole Core Contract -=== "EVM" +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +Keep in mind the following security considerations around relayers: - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks - ??? interface "Parameters" +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain - --- +## Client-Side Relaying - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + +### Key Features + +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure + +### Implementation + +Users themselves carry out the three steps of the cross-chain process: - --- +1. Perform an action on chain A - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +2. Retrieve the resulting VAA from the Guardian Network - ??? interface "Returns" +3. Perform an action on chain B using the VAA - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +### Considerations - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +- Users must sign all required transactions with their own wallet -// Check fee and send parameters +- Users must have funds to pay the transaction fees on every chain involved -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +- The user experience may be cumbersome due to the manual steps involved -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +## Custom Relayers -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -=== "Solana" +### Key Features - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - ??? interface "Parameters" +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +### Implementation - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +### Considerations - ??? child "Type `PostMessage<'info>`" +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +- Development work and hosting of relayers are required - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - --- +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - `batch_id` ++"u32"++ - - An identifier for the message batch. +## Wormhole Relayers - --- +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +### Key Features - --- +- **Lower operational costs** - no need to develop, host, or maintain individual relayers - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +### Implementation - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +The Wormhole relayer integration involves two key steps: - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` +### Considerations - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- All computations are performed on-chain -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +- Potentially less gas-efficient compared to custom relayers -### Receiving Messages +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted -The way a message is received and handled depends on the environment. +- Support may not be available for all chains -=== "EVM" +## Next Steps - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +
- ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- :octicons-book-16:{ .lg .middle } **Spy** - ??? interface "Parameters" + --- - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - ??? interface "Returns" + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - ??? child "Struct `VM`" + --- - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided + --- - ??? interface "Example" + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - // Perform safety checks here +
+--- END CONTENT --- - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - // Your custom application logic here -} - ``` +# Spy - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -=== "Solana" +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - Retrieve the raw message data: +## Key Features - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - ??? interface "Example" +## Integrator Use Case - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +## Observable Message Categories -#### Validating the Emitter +A Spy can access the following categories of messages shared over the gossip protocol: -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -await tx.wait(); -``` + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -#### Additional Checks +## Additional Resources -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: +
-- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + --- -## Source Code References + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + --- -# Wormhole Relayer + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -## Introduction + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. + --- -## Get Started with the Wormhole Relayer + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +
-
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+## Next Steps -### Wormhole Relayer Interfaces +
-There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +- :octicons-code-16:{ .lg .middle } **Run a Spy** -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + --- -## Interact with the Wormhole Relayer + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. +- :octicons-code-16:{ .lg .middle } **Use Queries** -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. + --- -Your initial set up should resemble the following: + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +
+--- END CONTENT --- -contract Example { - IWormholeRelayer public wormholeRelayer; +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +# Verified Action Approvals -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -### Send a Message +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +## VAA Format -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +The basic VAA consists of header and body components described as follows: -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: + Where each `signature` is: -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -### Receive a Message +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +## Consistency and Finality -## Delivery Guarantees +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +## Signatures -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -## Delivery Statuses +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +## Payload Types -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +### Token Transfer -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +Transferring tokens from the sending chain to the destination chain requires the following steps: -## Other Considerations +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: + +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -## Track the Progress of Messages with the Wormhole CLI +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +### Attestation -=== "Mainnet" +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -=== "Testnet" +The message format for token attestation is as follows: - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +#### Attestation Tips -## Step-by-Step Tutorial +Be aware of the following considerations when working with attestations: -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -# Products +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +### Token Transfer with Message -## Transfer Products +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -
+- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -::spantable:: +### Governance -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -::end-spantable:: +#### Action Structure -
+Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -## Bridging UI +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Real-time Data +#### Actions -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -## Multichain Governance +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +## Lifetime of a Message -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -# Wormhole Use Cases +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -
-
+1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -## Cross-Chain Swaps and Liquidity Aggregation +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -Enable seamless swaps between chains with real-time liquidity routing. +## Next Steps -
-
+
-🛠 **Wormhole products used:** +- :octicons-book-16:{ .lg .middle } **Guardians** -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution + --- -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -
-
+ [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -
-
+ --- -## Borrowing and Lending Across Chains + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -Let users borrow assets on one chain using collateral from another. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/)
-
+--- END CONTENT --- -🛠 **Wormhole products used:** +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +# Introduction to Wormhole -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -
-
+Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -
-
+![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -## Real-Time Price Feeds and Trading Strategies +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -Fetch price feeds across multiple chains for DeFi applications. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
-
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -🛠 **Wormhole products used:** +## What Problems Does Wormhole Solve? -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Critical problems Wormhole addresses include: -
-
+- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. +## What Does Wormhole Offer? -
-
+Wormhole provides a suite of tools and protocols that support a wide range of use cases: -## Asset Movement Between Bitcoin and Other Chains +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -Enable direct BTC transfers without wrapped assets. +## What Isn't Wormhole? -
-
+- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -🛠 **Wormhole products used:** +## Use Cases of Wormhole -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Consider the following examples of potential applications enabled by Wormhole: -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -
-
+## Explore -
-
+Discover more about the Wormhole ecosystem, components, and protocols: -## Decentralized Social Platforms +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -Enable seamless communication and asset transfer across decentralized social networks. +## Demos -
-
+Demos offer more realistic implementations than tutorials: -🛠 **Wormhole products used:** +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards + -
-
+!!! note + Wormhole Integration Complete? + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -## Memecoin Launchpads +## Supported Networks by Product -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -🛠 **Wormhole products used:** +# Security -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +## Core Security Assumptions -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -
-
+- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -## Cross-Chain Perpetuals +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -🛠 **Wormhole products used:** +### Governance -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -
-
+Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: -## Gas Abstraction +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -🛠 **Wormhole products used:** +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +Guardians monitor: -
-
+- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +## Asset Layer Protections -
-
+One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -## Bridging Intent Library +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -
-
+## Open Source -🛠 **Wormhole products used:** +Wormhole builds in the open and is always open source. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +## Audits -
-
+Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -
-
+All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -## Multichain Prediction Markets +## Bug Bounties -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -
-
+Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -🛠 **Wormhole products used:** +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +## Learn More -
-
+The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK -## Cross-Chain Payment Widgets +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +## Install the SDK -
-
+Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -🛠 **Wormhole products used:** +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +## Key Components -🔗 **Used in:** E-commerce, Web3 payments, and subscription models +The following key components and features work together to make your on-chain Wormhole integration easier to build. -
-
+??? interface "Base contracts" + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -## Oracle Networks +??? interface "Interfaces" -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -
-
+ - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -🛠 **Wormhole products used:** +??? interface "Constants" -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -
-
+## Example Usage +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: -## Cross-Chain Staking +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -Enable users to stake assets on one chain while earning rewards or securing networks on another. +### Set Up a Project -
-
+Follow these steps to prepare your development environment: -🛠 **Wormhole products used:** +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -
-
---- END CONTENT --- + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -## Reference Concepts [shared: true] +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` ---- + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -## List of shared concept pages: + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -## Full content for shared concepts: +## Use Contracts to Transfer USDC -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -# Reference + ```bash + touch script/transfer.ts + ``` -## Get Started +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -
+ // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); - --- + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); - --- + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); + + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -3427,7 +3647,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -3482,7 +3702,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -3698,262 +3918,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -3965,7 +4019,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -4140,7 +4194,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -4221,4 +4275,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-ntt.txt b/llms-files/llms-ntt.txt index 91d42f84d..e6a6d462c 100644 --- a/llms-files/llms-ntt.txt +++ b/llms-files/llms-ntt.txt @@ -13,104 +13,24 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/deployment.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/overview.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/security.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/cli-commands.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/access-control.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/rate-limiting.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/installation.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/post-deployment.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/troubleshooting.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/managers-transceivers.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/security.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/access-control.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/rate-limiting.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-evm.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-solana.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/evm-launchpad.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/post-deployment.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/troubleshoot.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/cli-commands.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/managers-transceivers.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/ ---- BEGIN CONTENT --- ---- -title: A Quick Look at Native Token Transfers -description: This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- - -# Native Token Transfers - -## Get Started - -This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. - -
- -- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Dive into an introduction to NTT and discover what NTT is, what its key features are, and the available integration paths. - - [:custom-arrow: Learn more about NTT](/docs/learn/transfers/native-token-transfers/overview/) - -- :octicons-question-16:{ .lg .middle } **Architecture** - - --- - - Explore NTT's architecture to understand its core components and how they work together to manage cross-chain communication. - - [:custom-arrow: Discover how NTT works](/docs/learn/transfers/native-token-transfers/architecture/) - -- :octicons-book-16:{ .lg .middle } **Deployment Models** - - --- - - The NTT framework offers two deployment models for different token management needs: the hub-and-spoke and burn-and-mint models. - - [:custom-arrow: Check out the deployment models](/docs/learn/transfers/native-token-transfers/deployment/) - -- :octicons-shield-lock-16:{ .lg .middle } **Security** - - --- - - Explore NTT's security measures, including the Global Accountant and governance strategies for seamless token safety. - - [:custom-arrow: Review the security measures](/docs/learn/transfers/native-token-transfers/security/) - -
- -## Next Steps - -Ready to dive in and start building? Check out the following resources to begin the deployment process and make the most of your deployment. - -
- -- :octicons-rocket-16:{ .lg .middle } **Deploy NTT** - - --- - - Explore detailed guides that walk you through the entire deployment process, from installing the NTT CLI to deploying NTT across supported chains. - - [:custom-arrow: Deploy now using the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/) - -- :octicons-checklist-16:{ .lg .middle } **Post Deployment Recommendations** - - --- - - Already deployed your NTT project? Check out these post deployment recommendations and integration demos to get the most out of your deployment. - - [:custom-arrow: Get the most of out your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/architecture/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/architecture/ --- BEGIN CONTENT --- --- title: Native Token Transfers Architecture @@ -122,7 +42,6 @@ categories: NTT, Transfer The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. -For the technical implementations of the functions, refer to the [Managers and Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/){target=\_blank} page. ## System Components @@ -164,10 +83,10 @@ How it works: 2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred 3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain -![NTT architecture diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-1.webp) +![NTT architecture diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-1.webp) !!! note - [Learn more](/docs/learn/transfers/native-token-transfers/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. + [Learn more](/docs/products/native-token-transfers/concepts/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. #### Custom Transceivers @@ -175,7 +94,7 @@ The NTT framework supports advanced features such as custom transceivers for spe NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. -![Custom Attestation with NTT diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-2.webp) +![Custom Attestation with NTT diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-2.webp) The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. @@ -233,113 +152,7 @@ Finally, after the message is verified and attested to, the tokens can be either In both cases, once the tokens have been released, the transfer process is complete, and the recipient receives the tokens. Events are emitted to indicate that the transfer has been fully redeemed. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/deployment/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers - Deployment Models -description: Explore Wormhole's Native Token Transfers deployment models——hub-and-spoke, burn-and-mint——for seamless cross-chain token transfers. -categories: NTT, Transfer ---- - -# Deployment Models - -The Wormhole framework offers two deployment models, each catering to different token management needs: the hub-and-spoke model and the burn-and-mint model. These models provide flexible solutions for both existing token deployments and new projects looking to enable secure and seamless multichain token transfers. - -## Hub-and-Spoke - -The hub-and-spoke model involves locking tokens on a central hub chain and minting them on destination spoke chains. This model maintains the total supply on the hub chain and is backward-compatible with any existing token deployment. - -This model is ideal for existing token deployments that don't want to alter existing token contracts. It maintains the canonical balance on a hub chain while allowing for secure native deployment to new blockchains. - -- **Hub chain** - tokens are locked when initiating a transfer -- **Spoke chains** - Equivalent tokens are minted on the destination chain - -When transferring tokens back to the original hub chain, the tokens on the source spoke chain are burned, and the previously locked tokens on the hub chain are unlocked. However, when transferring tokens directly between spoke chains, the tokens are burned on the source spoke chain and minted on the destination spoke chain. - -## Burn-and-Mint - -The burn-and-mint model involves burning tokens on the source chain and minting them on the destination chain. This results in a simplified multichain transfer process that distributes the total supply across multiple chains and produces a native multichain token. - -This model best suits new token deployments or projects willing to upgrade existing contracts. - -- **Source chain** - tokens are burned when initiating a transfer -- **Destination chain** - equivalent tokens are minted on the destination chain ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/overview/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Overview -description: Explore Wormhole's Native Token Transfers for flexible cross-chain transfers with full control over token behavior, security, and integration features. -categories: NTT, Transfer ---- - -# Native Token Transfers - -!!!tip "Looking to deploy NTT?" - If you're ready to deploy NTT or access the CLI, follow the detailed [NTT Deployment Section](/docs/build/transfers/native-token-transfers/deployment-process/){target=\_blank}. - - - For deployment steps on EVM, visit the [Deploy to EVM page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} - - For deployment steps on Solana, visit the [Deploy to Solana page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/){target=\_blank} - -## Introduction - -Wormhole's Native Token Transfers (NTT) is an open source, flexible, and composable framework for transferring tokens across blockchains. By eliminating wrapped assets, NTT preserves each token’s native properties across chains, letting you maintain complete control over metadata, ownership, upgrade authority, and other custom features. - -The framework offers two modes of operation for existing token deployments. In locking mode, the original token supply is preserved on a single chain. In contrast, the burning mode enables the deployment of multichain tokens, distributing the supply across various chains. - -## Key Features - -Wormhole's Native Token Transfers (NTT) framework offers a comprehensive and flexible solution for seamless token transfers across blockchains. Below are some of the key features that make this framework stand out: - -- **No wrapped tokens** – tokens remain native on every chain where NTT is deployed. All token properties and metadata remain consistent, avoiding any confusion or overhead introduced by wrapped tokens -- **Unified user experience** - tokens retain their properties on each chain, remaining completely fungible and ensuring a consistent user experience -- **No liquidity pools** - transfer tokens without the need for liquidity pools, avoiding fees, slippage, and MEV risk -- **Integrator flexibility** - retained ownership, upgrade authority, and complete customizability over token contracts -- **Advanced rate limiting** - inbound and outbound rate limits are configurable per chain and over arbitrary periods, preventing abuse while managing network congestion and allowing for controlled deployments to new chains -- **Global Accountant** - ensures accounting integrity across chains by checking that the number of tokens burned and transferred out of a chain never exceeds the number of tokens minted -- **Access control** - to prevent unauthorized calls to administrative functions, protocols can choose to assign specific functions, such as the Pauser role, to a separate address from the owner -- **Maximum composability** - open source and extensible for widespread adoption and integration with other protocols -- **Custom attestation** - optionally add external verifiers and configure custom message attestation thresholds - -## Integration Paths - -Integrators looking to deploy their token to connected chains can use the NTT framework or the Token Bridge. Both options carry a distinct integration path and feature set depending on your requirements, as outlined in the following sections. - -### Native Token Transfers Framework - -The Native Token Transfers Framework is highly customizable and ideal for applications such as a DeFi governance token deployed across multiple chains, which seeks to achieve fungible multichain liquidity and direct integration into governance processes. - -- **Mechanism** - can entirely utilize a burn-and-mint mechanism or can be paired for a hub-and-spoke model -- **Security** - fully configurable rate limiting, pausing, access control, and threshold attestations. Integrated with the Global Accountant -- **Contract ownership** - retain ownership and upgrade authority of token contracts on each chain -- **Token contracts** - native contracts owned by your protocol governance -- **Integration** - streamlined, customizable framework allows for more sophisticated and bespoke deployments - -The following example projects demonstrate the use of the Wormhole NTT framework through Wormhole Connect and the TypeScript SDK: - -- [NTT Connect](https://github.com/wormhole-foundation/demo-ntt-connect){target=\_blank} -- [NTT TS SDK](https://github.com/wormhole-foundation/demo-ntt-ts-sdk){target=\_blank} - -### Token Bridge - -The Token Bridge offers a secure, low-effort integration suitable for applications like a Web3 game that wants to make its token tradable across multiple chains. - -- **Mechanism** - solely utilizes a lock and mint model. Unlike NTT, the Token Bridge issues a wrapped asset on the destination chain, rather than preserving the original token contract -- **Security** - preconfigured rate limiting and integrated Global Accountant -- **Contract ownership** - Token Bridge contracts are upgradeable via [Wormhole Governance](/docs/learn/security/){target=\_blank} -- **Token contracts** - wrapped asset contract owned by the Wormhole Token Bridge contract, upgradeable via a 13/19 Guardian governance process -- **Integration** - straightforward and permissionless method to deploy on multiple chains - -!!! note - [Learn more](/docs/learn/infrastructure/vaas/){target=\_blank} about the core messaging primitives in the Wormhole network. - -## Supported Token Standards - -Native Token Transfers (NTT) in Wormhole primarily support **ERC-20 tokens**, the most widely used standard for fungible tokens on the Ethereum network and other EVM-compatible blockchains. The NttManager contract leverages the IERC20 interface and SafeERC20 utility from OpenZeppelin to ensure secure and efficient token transfers. Additionally, it supports ERC-20 Burnable tokens, allowing tokens to be burned on the source chain when needed for cross-chain transfers. At this time, NTT focuses on ERC-20 tokens, and other token standards, such as ERC-721 (non-fungible tokens) or ERC-1155 (multi-token standard), are not natively supported. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/security/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/security/ --- BEGIN CONTENT --- --- title: Native Token Transfers Security @@ -371,169 +184,7 @@ The registry component of the NTT system is crucial for maintaining a trusted li This governance model ensures that the system remains secure while being adaptable to new requirements in any environment where it is deployed. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers (NTT) -description: This section provides comprehensive guidance on configuring, deploying, and managing your Native Token Transfers (NTT) integration. -categories: NTT, Transfer ---- - -# Native Token Transfers - -Native Token Transfers (NTT) simplifies and enables seamless, flexible token transfers across blockchains. This section provides comprehensive guidance on configuring, deploying, and managing your NTT integration. It includes information relevant to both new token deployments and existing token management. - -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} and [Product Comparison](/docs/build/start-building/products/){target=\_blank} pages for help determining if NTT will meet the needs of your project. - -## Quickstart - -If needed, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. - -The process for creating, deploying, and monitoring NTTs is as follows. Select the title of each step to view the associated guide: - -[timeline left(wormhole-docs/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json)] - -## Deploy NTTs with Launchpad - -If you are deploying to EVM blockchains, the [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT. NTT Launchpad replaces manually deploying contracts or configuring relayers for each supported EVM chain. - -Follow the [Deploy NTT with Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/){target=\_blank} guide to create new multichain tokens or integrate existing tokens with just a few clicks. - -## Additional Resources - -
- -- :octicons-gear-16:{ .lg .middle } **NTT CLI Commands** - - --- - - The NTT CLI tool provides a comprehensive set of commands for creating, configuring, deploying, and monitoring NTTs. This page provides a comprehensive list of available NTT CLI commands, their descriptions, and examples to help you interact effectively with the NTT system. - - [:custom-arrow: NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/) - -- :octicons-question-16:{ .lg .middle } **NTT FAQs** - - --- - - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. - - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/cli-commands/ ---- BEGIN CONTENT --- ---- -title: NTT CLI Commands -description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. -categories: NTT, Transfer ---- - -# NTT CLI Commands - -## Introduction - -The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. - -If you haven't installed the NTT CLI yet, follow the [NTT Installation Guide](/docs/build/transfers/native-token-transfers/deployment-process/installation/#installation){target=\_blank} to set it up before proceeding. - -## Table of Commands - -The following table lists the available NTT CLI commands, descriptions, and examples. - -To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. - -### General Commands - -| Command | Description | Examples | -|-----------------------------------------|-------------------------------------------------------|--------------------------| -| `ntt update` | update the NTT CLI | `ntt update` | -| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | -| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest`| -| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0`| -| `ntt clone
` | initialize a deployment file from an existing contract| `ntt clone Mainnet Solana Sol5678...`| -| `ntt init ` | initialize a deployment file | `ntt init devnet` | -| `ntt pull` | pull the remote configuration | `ntt pull` | -| `ntt push` | push the local configuration | `ntt push` | -| `ntt status` | check the status of the deployment | `ntt status` | - -### Configuration Commands - -| Command | Description | Examples | -|---------------------------------------------|----------------------------------------|-------------------------------------| -| `ntt config set-chain `| set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key`| -| `ntt config unset-chain ` | unset a configuration value for a chain| `ntt config unset-chain Ethereum scan_api_key`| -| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key`| - -### Solana Commands - -| Command | Description | Examples | -|-----------------------------------------------|---------------------------------------------------------|------------------| -| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json`| -| `ntt solana token-authority ` | print the token authority address for a given program ID| `ntt solana token-authority Sol1234...`| -| `ntt solana ata `| print the token authority address for a given program ID| `ntt solana ata Mint123... Owner123... token22`| - -## Where to Go Next - -
- - -- :octicons-gear-16:{ .lg .middle } **Configure NTT** - - --- - - Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - - [:custom-arrow: Configure your NTT deployment](/docs/build/transfers/native-token-transfers/configuration/) - -- :octicons-question-16:{ .lg .middle } **NTT FAQs** - - --- - - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. - - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers (NTT) - Configuration -description: This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -categories: NTT, Transfer ---- - -# Configure Native Token Transfers (NTT) - -## Get Started - -This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - -
- -- :octicons-clock-16:{ .lg .middle } **Rate Limiting** - - --- - - Discover options for configuring rate limits and how queueing effects transaction flow. - - [:custom-arrow: Explore rate limit options](/docs/build/transfers/native-token-transfers/configuration/rate-limiting/) - -- :octicons-unlock-16:{ .lg .middle } **Access Control** - - --- - - Learn more about access control, including why you should consider setting a separate Pauser address as part of your development security plan. - - [:custom-arrow: Explore access control roles](/docs/build/transfers/native-token-transfers/configuration/access-control/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/access-control/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/access-control/ --- BEGIN CONTENT --- --- title: Native Token Transfers Access Control @@ -577,7 +228,7 @@ The `Owner` and the `Pauser` addresses can each pause the contract. Since the co Consider separating `Owner` and `Pauser` roles for your multichain deployment. `Owner` and `Pauser` roles are defined directly on the `NttManager` contract. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/rate-limiting/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/rate-limiting/ --- BEGIN CONTENT --- --- title: Native Token Transfers Rate Limiting @@ -676,74 +327,371 @@ Queuing is configured dynamically during each transfer by passing the `shouldQue If users bridge frequently between a given source chain and destination chain, the capacity could be exhausted quickly. Loss of capacity can leave other users rate-limited, potentially delaying their transfers. The outbound transfer cancels the inbound rate limit on the source chain to avoid unintentional delays. This allows for refilling the inbound rate limit by an amount equal to the outbound transfer amount and vice-versa, with the inbound transfer canceling the outbound rate limit on the destination chain and refilling the outbound rate limit with an amount. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/faqs/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) - Deployment -description: This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. +title: Native Token Transfers FAQs +description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. categories: NTT, Transfer --- -# Deploy Native Token Transfers (NTT) +# Wormhole NTT FAQs -## Get Started +## Do you have an example of how cross-chain lending can be implemented using Wormhole? -This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. +Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. -
+Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/products/messaging/overview/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. -- :octicons-download-16:{ .lg .middle } **Installation** +## What causes the "No protocols registered for Evm" error in Wormhole SDK? - --- +This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. - Prerequisites and commands for installing the NTT CLI and working with the NTT framework. +To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: - [:custom-arrow: Install the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/) +```rust +import '@wormhole-foundation/sdk-evm-ntt'; +``` -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** +By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. - --- +## How can I transfer ownership of NTT to a multisig? - Find information on preparing for NTT deployment to EVM, including an example NTT token repository. +Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) +1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) +2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer +3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains via Launchpad** +For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. - --- +## How can I specify a custom RPC for NTT? - Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. +To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. - [:custom-arrow: Deploy via Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/) +Below’s an example of how the `overrides.json` file should be structured: -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +???- code "`overrides.json`" + ```json + { + "chains": { + "Bsc": { + "rpc": "http://127.0.0.1:8545" + }, + "Sepolia": { + "rpc": "http://127.0.0.1:8546" + }, + "Solana": { + "rpc": "http://127.0.0.1:8899" + } + } + } + ``` - --- +## How can I redeem tokens if NTT rate limits block them on the target chain? - Your guide to NTT deployment to Solana, including setup, token compatibility, mint/burn modes, and CLI usage. +If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) +To resolve this: -- :octicons-search-16:{ .lg .middle } **Post Deployment** +1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed +2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain - --- +In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. - Learn how to best monitor and maintain your NTT deployment to get the most out of your Wormhole integration while providing security for users. +## What are the challenges of deploying NTT to non-EVM chains? - [:custom-arrow: Explore next steps](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) +NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. -- :octicons-alert-16:{ .lg .middle } **Troubleshooting** +## Does the NTT manager function as an escrow account for a hub chain? - --- +Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. - Explore solutions and detailed guidance in our troubleshooting guide to resolve issues with NTT deployment. +## Which functions or events does Connect rely on for NTT integration? - [:custom-arrow: Get help](/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/) +Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: -
+- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain +- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion + +These functions ensure Connect can handle token transfers and manage chain-rate limits. + +## How does the relayer contract determine which transceiver to call? + +The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. + +## How do I create a verifier or transceiver? + +To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. + +For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. + +## Can I use Hetzner for the NTT deployment? + +No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. + +## How can I transfer tokens with NTT with an additional payload? + +You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. + +- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message +- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message + +!!!Important + You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. + +## Why use NTT over xERC20? + +Shortcomings of xERC20: + +- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach +- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies +- **No access control** - there are no built-in access controls for managing token transfers securely +- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security +- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups + +While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. + +## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? + +To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. + +## Is there a way to use NTT tokens with chains that don't currently support NTT? + +Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. For example: + +- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) +- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism +- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT + +This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. + +## How can I update my NTT CLI version? + +To update an existing NTT CLI installation, run the following command in your terminal: + +```bash +ntt update +``` + +NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. + +For local development, you can update your CLI version from a specific branch or install from a local path. + +To install from a specific branch, run: + +```bash +ntt update --branch foo +``` + +To install locally, run: +```bash +ntt update --path path/to/ntt/repo +``` + +Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with NTT +description: NTT enables cross-chain token movement without wrapping. Install the CLI, deploy test tokens, and scaffold a project to integrate NTT into your app. +categories: NTT, Transfer +--- + +# Get Started with NTT + +## Introduction + +The [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview){target=\_blank} framework enables seamless cross-chain token movement without wrapping or liquidity pools. This guide shows you how to install the NTT CLI, which is used to configure and deploy native token contracts, and scaffold your first project for deployment on testnet or mainnet. + +If you are looking for a no-code experience to deploy on mainnet, you can explore the [NTT Launchpad](https://ntt.wormhole.com){target=\_blank}. + +## Prerequisites + +Before you begin, make sure you have: + +- [Node.js and npm installed](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} +- [Bun installed](https://bun.sh/){target=\_blank} +- A wallet private key with tokens on supported chains +- ERC-20 or SPL tokens already deployed on the source and destination chains + +## Don’t Have a Token Yet? + +To use NTT, you must have a token already deployed on the source and destination chains. If you don’t have one, follow the quick guides below to deploy a basic test token. + +???- interface "Deploy an ERC-20 Token on EVM" + Use the [example NTT token repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} to deploy a basic ERC-20 token contract on testnet. + + 1. **Install Foundry** - install the [Forge CLI](https://book.getfoundry.sh/getting-started/installation){target=\_blank} + + 2. **Clone the repository** – fetch the example contract repository + + ```bash + git clone https://github.com/wormhole-foundation/example-ntt-token.git + cd example-ntt-token + ``` + + 3. **Deploy the token contract** – deploy to testnet with your preferred name, symbol, minter, and owner addresses + + ```bash + forge create --broadcast \ + --rpc-url INSERT_RPC_URL \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + src/PeerToken.sol:PeerToken \ + --constructor-args "INSERT_TOKEN_NAME" "INSERT_TOKEN_SYMBOL" INSERT_MINTER_ADDRESS INSERT_OWNER_ADDRESS + ``` + + 4. **Mint tokens** – send tokens to your address + + ```bash + cast send INSERT_TOKEN_ADDRESS \ + "mint(address,uint256)" \ + INSERT_RECIPIENT_ADDRESS \ + INSERT_AMOUNT_IN_WEI \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + --rpc-url INSERT_RPC_URL + ``` + + !!! note + This token uses 18 decimals by default. All minting values must be specified in `wei` (1 token = 10^18). + + +???- interface "Create and Mint SPL Tokens" + This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. + + 1. **Generate a Solana key pair** - run the following command to create a new wallet: + + ```bash + solana-keygen grind --starts-with w:1 --ignore-case + ``` + + 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: + + ```bash + solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON + ``` + + 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: + + === "Mainnet" + ```bash + solana config set -um + ``` + + === "Testnet" + ```bash + solana config set -ut + ``` + + === "Devnet" + ```bash + solana config set -ud + ``` + + 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: + + ```bash + solana airdrop 2 + solana balance + ``` + + 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} + + ```bash + cargo install spl-token-cli + ``` + + 6. **Create a new SPL token** - initialize the token on Solana + + ```bash + spl-token create-token + ``` + + 7. **Create a token account** - generate an account to hold the token + + ```bash + spl-token create-account INSERT_TOKEN_ADDRESS + ``` + + 8. **Mint tokens** - send 1000 tokens to the created account + + ```bash + spl-token mint INSERT_TOKEN_ADDRESS 1000 + ``` + + !!! note + NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. + +## Install NTT CLI + +
+ +The NTT CLI is recommended to deploy and manage your cross-chain token configuration. + +1. Run the installation command in your terminal: + + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` + +2. Verify the NTT CLI is installed: + + ```bash + ntt --version + ``` + +## Initialize a New NTT Project + +1. Once the CLI is installed, scaffold a new project by running: + + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` + +2. Initialize a new `deployment.json` file specifying the network: + + === "Mainnet" + ```bash + ntt init Mainnet + ``` + + === "Testnet" + ```bash + ntt init Testnet + ``` + + After initialization, the `deployment.json` file contains your NTT configuration and starts with the selected network. + + === "Mainnet" + ```json + { + "network": "Mainnet", + "chains": {} + } + ``` + + === "Testnet" + ```json + { + "network": "Testnet", + "chains": {} + } + ``` + +In the deployment steps, you will add your supported chains, their token addresses, deployment modes, and any custom settings. + +## Next Steps + +You have scaffolded your NTT project and initialized the configuration file. Next, follow the appropriate guide below to configure your supported chains and deploy NTT contracts: + +- [Deploy to EVM](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank}: Deploy NTT on EVM-compatible chains. +- [Deploy to Solana](/docs/products/native-token-transfers/guides/deploy-to-solana/){target=\_blank}: Deploy NTT on Solana. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-evm/ --- BEGIN CONTENT --- --- title: Native Token Transfers EVM Deployment @@ -751,7 +699,11 @@ description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for categories: NTT, Transfer --- -# Native Token Transfers (NTT) EVM Development +# Deploy Native Token Transfers (NTT) to EVM Chains + +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of ERC-20 tokens on [supported EVM-compatible chains](/docs/products/reference/supported-networks/#ntt){target=\_blank} using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. + +This guide walks you through deploying NTT on EVM chains, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. ## Deploy Your Token and Ensure Compatibility @@ -759,20 +711,20 @@ If you still need to do so, deploy the token contract to the destination or spok ### Requirements for Token Deployment -Wormhole’s NTT is an open framework that supports various deployment modes. The NTT CLI currently supports two deployment modes: burn-and-mint and hub-and-spoke. These modes differ in how tokens are managed across chains. +Wormhole’s NTT framework supports two [deployment models](/docs/products/native-token-transfers/overview#deployment-models){target=\_blank}: burn-and-mint and hub-and-spoke. **Both require an ERC-20 token (new or existing).** -#### Burn-and-Mint Mode +??? interface "Burn-and-Mint" -Tokens integrated with `NttManager` in `burning` mode require the following two functions to be present: + Tokens must implement the following non-standard ERC-20 functions: -- `burn(uint256 amount)` -- `mint(address account, uint256 amount)` + - `burn(uint256 amount)` + - `mint(address account, uint256 amount)` -These functions aren't part of the standard ERC-20 interface. The [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} documents the required functions and convenience methods, errors, and events. + These functions aren't part of the standard ERC-20 interface. Refer to the [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} for all required functions, errors, and events. -??? code "View the complete `INttToken` Interface`" - ```solidity - // SPDX-License-Identifier: Apache 2 + ??? interface "`INttToken` Interface" + ```solidity + // SPDX-License-Identifier: Apache 2 pragma solidity >=0.8.8 <0.9.0; interface INttToken { @@ -808,54 +760,86 @@ interface INttToken { // found in the `ERC20Burnable` interface. function burn(uint256 amount) external; } - ``` - -Later, you set mint authority to the corresponding `NttManager` contract. You can also follow the scripts in the [example NTT token](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} repository to deploy a token contract. + ``` -#### Hub-and-Spoke Mode + You’ll also need to set mint authority to the relevant `NttManager` contract. Example deployment scripts are available in the [`example-ntt-token` GitHub repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank}. -A central hub chain (e.g., Ethereum) manages the total token supply in hub-and-spoke mode. Other chains (spokes) mint or burn tokens during cross-chain transfers, ensuring consistency with the locked tokens on the hub chain. +??? interface "Hub-and-Spoke Mode" - - **Hub chain** - tokens are locked on the hub chain when transferring to spoke chains - - **Spoke chains** - tokens are native to the spoke chains and are either minted or burned during cross-chain transfers + Tokens only need to be ERC-20 compliant. The hub chain serves as the source of truth for supply consistency, while only spoke chains need to support minting and burning. For example, if Ethereum is the hub and Polygon is a spoke: -!!! note - The only requirement for using the NTT framework is an ERC20 token, which can be newly deployed or existing. Steps like setting mint authority apply only to spoke chains. + - Tokens are locked on Ethereum + - Tokens are minted or burned on Polygon -For example, when transferring tokens from Ethereum (hub) to Polygon (spoke), the NTT Manager locks tokens on Ethereum, and the corresponding amount is minted on Polygon. Similarly, transferring tokens back from Polygon to Ethereum burns the tokens on Polygon and unlocks the equivalent tokens on Ethereum. + This setup maintains a consistent total supply across all chains. -This process ensures that the total token supply remains consistent across all chains, with the hub chain acting as the source of truth. +## NTT Manager Deployment Parameters -For more detailed information, see the [Deployment Models](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank} page. +This table compares the configuration parameters available when deploying the NTT Manager using the CLI versus a manual deployment with a Forge script. It highlights which options are configurable via each method, whether values are auto-detected or hardcoded, and includes additional comments to help guide deployment decisions. -### Key Differences Between Modes +|
Parameter
| Forge Script | CLI | Both | Comments | +|-------------------------|------------------------|-------------------------------------|--------|----------------------------------------------| +| `token` | Input | `--token
` | Yes | | +| `mode` | Input | `--mode ` | Yes | Key decision: hub-and-spoke or mint-and-burn | +| `wormhole` | Input | Auto-detected via SDK/`ChainContext` | Similar| | +| `wormholeRelayer` | Input | Auto-detected via on-chain query/SDK| Similar| | +| `specialRelayer` | Input | Not exposed | No | Take into consideration if using custom relaying. Not recommended | +| `decimals` | Input, overridable | Auto-detected via token contract, not overridable | Similar | | +| `wormholeChainId` | Queried from Wormhole contract | `--chain` (network param, mapped internally) | Yes | | +| `rateLimitDuration` | Hardcoded (`86400`) | Hardcoded (`86400`) | Yes | Rate limit duration. A day is normal but worth deciding | +| `shouldSkipRatelimiter` | Hardcoded (`false`) | Hardcoded (`false`) | Yes | If rate limit should be disabled (when the manager supports it) | +| `consistencyLevel` | Hardcoded (`202`) | Hardcoded (`202`) | Yes | `202` (finalized) is the standard — lower is not recommended | +| `gasLimit` | Hardcoded (`500000`) | Hardcoded (`500000`) | Yes | | +| `outboundLimit` | Computed | Auto-detected/Hardcoded | Similar| Relative to rate limit | - - **Burn-and-mint** - tokens must implement custom `mint` and `burn` functions, allowing each chain to manage token issuance independently - - **Hub-and-spoke** - tokens only need to be ERC20 compliant, with the hub chain acting as the source of truth for supply consistency ## Deploy NTT -Create a new NTT project: +Before deploying NTT contracts on EVM chains, you need to scaffold a project and initialize your deployment configuration. -```bash -ntt new my-ntt-deployment -cd my-ntt-deployment -``` +???- interface "Install the NTT CLI and Scaffold a New Project" + + Before proceeding, make sure you have the NTT CLI installed and a project initialized. -Initialize a new `deployment.json` file specifying the network: +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): -=== "Testnet" +1. Install the NTT CLI: ```bash - ntt init Testnet + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash ``` -=== "Mainnet" + Verify installation: + + ```bash + ntt --version + ``` + +2. Initialize a new NTT project: ```bash - ntt init Mainnet + ntt new my-ntt-project + cd my-ntt-project ``` +3. Create the deployment config**: + + === "Mainnet" + + ```bash + ntt init Mainnet + ``` + + === "Testnet" + + ```bash + ntt init Testnet + ``` + + This generates a `deployment.json` file where your deployment settings will be stored. + +Once you've completed those steps, return here to proceed with adding your EVM chains and deploying contracts. + Ensure you have set up your environment correctly: ```bash @@ -930,10 +914,10 @@ The final step in the deployment process is to set the NTT Manager as a minter o By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. !!!important - To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} page. + To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} page. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-solana/ --- BEGIN CONTENT --- --- title: Native Token Transfers Solana Deployment @@ -943,11 +927,9 @@ categories: NTT, Transfer # Deploy Native Token Transfers on Solana -[Native Token Transfers (NTT)](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. -This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. - -By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. +This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. ## Prerequisites @@ -1034,31 +1016,51 @@ Deploying NTT with the CLI on Solana follows a structured process: !!! note NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. -2. **Choose your [deployment model](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank}**: +2. **Choose your deployment model**: - - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required - - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program + - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required + - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program 3. **Deploy and configure NTT** - use the NTT CLI to initialize and deploy the NTT program, specifying your SPL token and deployment mode +![Solana NTT deployment diagram](/docs/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp) + Following this process, your token will fully integrate with NTT, enabling seamless transfers between Solana and other chains. -By default, NTT transfers to Solana require manual [relaying](/docs/learn/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. +By default, NTT transfers to Solana require manual [relaying](/docs/protocol/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. ## Set Up NTT To integrate your token with NTT on Solana, you must initialize the deployment and configure its parameters. This process sets up the required contracts and may generate key pairs if they don't exist. These key pairs are used to sign transactions and authorize actions within the NTT deployment. -The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: +The [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: + +???- interface "Install the NTT CLI and Scaffold a New Project" + + Before proceeding, make sure you have the NTT CLI installed and a project initialized. + +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): + +1. Install the NTT CLI: + + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` + + Verify installation: + + ```bash + ntt --version + ``` -1. **Create a new NTT project** - set up a deployment workspace +2. Initialize a new NTT project: ```bash - ntt new INSERT_PROJECT_NAME - cd INSERT_PROJECT_NAME + ntt new my-ntt-project + cd my-ntt-project ``` -2. **Initialize the deployment** - generate a `deployment.json` file with your deployment settings +3. Create the deployment config**: === "Mainnet" @@ -1071,17 +1073,19 @@ The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/in ```bash ntt init Testnet ``` -!!! note - Testnet deployment settings work for both Solana Testnet and Devnet networks. + This generates a `deployment.json` file where your deployment settings will be stored. + + !!! note + Testnet deployment settings work for both Solana Testnet and Devnet networks. ### Generate an NTT Program Key Pair Create a unique key pair for the NTT program: - - ```bash - solana-keygen grind --starts-with ntt:1 --ignore-case - ``` + +```bash +solana-keygen grind --starts-with ntt:1 --ignore-case +``` ### Set Mint Authority @@ -1108,7 +1112,7 @@ Follow these steps to set the mint authority using the NTT CLI: ## Deploy and Configure NTT !!! warning - If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/build/transfers/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. + If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/products/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. After setting up your deployment, finalize the configuration and deploy the NTT program on Solana by following these steps: @@ -1174,7 +1178,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i After deploying NTT on Solana, deploy and integrate it on EVM chains to enable seamless multichain transfers. - [:custom-arrow: Deploy NTT on EVM](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} + [:custom-arrow: Deploy NTT on EVM Chains](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Test Your Deployment** @@ -1182,7 +1186,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Follow the NTT Post Deployment Guide for integration examples and testing instructions. - [:custom-arrow: Test Your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} + [:custom-arrow: Test Your NTT deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Add NTT to Your dApp** @@ -1190,7 +1194,15 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Configure Wormhole Connect, a plug-and-play bridging UI, to enable multichain transfers for your token. - [:custom-arrow: Use Connect to Integrate NTT](/docs/build/transfers/connect/){target=\_blank} + [:custom-arrow: Use Connect to Integrate NTT](/docs/products/connect/overview/){target=\_blank} + +- :octicons-question-16:{ .lg .middle } **View FAQs** + + --- + + Find answers to common questions about NTT. + + [:custom-arrow: View FAQs](/docs/products/native-token-transfers/faqs){target=\_blank} - :octicons-question-16:{ .lg .middle } **View FAQs** @@ -1203,7 +1215,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/evm-launchpad/ --- BEGIN CONTENT --- --- title: Deploy Native Token Transfers with Launchpad @@ -1250,8 +1262,8 @@ The NTT Launchpad currently supports deployments on the following mainnet chains Once ready, choose an option to proceed: - - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token) - deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains - - [**Expand Your Existing Token**](#expand-your-existing-token) - if you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract + - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token): Deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains. + - [**Expand Your Existing Token**](#expand-your-existing-token): If you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract. ## Launch a Cross-Chain Token @@ -1259,11 +1271,11 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Launch a Cross-Chain Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp) 3. Set the token details: 1. Select the **home network** from the dropdown menu @@ -1272,22 +1284,22 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 4. Provide the **initial supply** 5. To the token details, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp) 4. Select the deployment chains: 1. The home network where your token will be deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -1299,33 +1311,33 @@ Expand an existing token to support NTT across multiple chains. This process int 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Expand Your Existing Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp) 3. Enter the token details: 1. Choose the home network where your token is already deployed (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp) 4. Select the chains to deploy your token to: 1. The home network where your token is already deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 1. Click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -1335,7 +1347,7 @@ Expand an existing token to support NTT across multiple chains. This process int To access the **Dashboard** from the [Launchpad home page](https://ntt.wormhole.com/){target=\_blank}, click on **Manage Deployment**. Here, you can view deployment status, monitor supply across chains, and configure transfer settings. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp) The dashboard provides a high-level view of your token across all deployed chains, including: @@ -1343,7 +1355,7 @@ The dashboard provides a high-level view of your token across all deployed chain - Supply distribution visualization - List of deployed chains, including inbound and outbound transfer limits, which can be modified in [**Settings**](#settings) -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp) ## Settings @@ -1355,131 +1367,44 @@ Use the drop-down menu at the top to select the chain you want to configure. The From this section, you can also: - - **Pause the token** – temporarily turn off transfers on the selected chain - - **Deploy to a new chain** – expand your token by deploying it to an additional chain + - **Pause the token**: Temporarily turn off transfers on the selected chain. + - **Deploy to a new chain**: Expand your token by deploying it to an additional chain. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp) ### Role Management -This section displays key [roles](/docs/build/transfers/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. +This section displays key [roles](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. - - **Manager’s Owner** – the owner through the `NTTOwner` proxy - - **Pauser** – the address authorized to pause transfers + - **Manager’s Owner**: The owner through the `NTTOwner` proxy. + - **Pauser**: The address authorized to pause transfers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp) ### Security Threshold -Determine and update how transceivers interact with the token. [Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. +Determine and update how transceivers interact with the token. [Transceivers](/docs/products/native-token-transfers/concepts/architecture/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. A higher transceiver threshold increases security by requiring more approvals before processing a transfer, but it may also slow down transactions. A lower threshold allows faster transfers but reduces redundancy in message verification. - - **Registered Transceivers** – displays the number of registered transceivers and their addresses - - **Transceivers Threshold** – a configurable value that must be less than or equal to the number of transceivers + - **Registered Transceivers**: Displays the number of registered transceivers and their addresses. + - **Transceivers Threshold**: A configurable value that must be less than or equal to the number of transceivers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp) ### Peer Chains Limits Define the transfer restrictions for each connected network. You can adjust: - - **Sending Limits** – the maximum amount of tokens that can be sent from the home chain - - **Receiving Limits** – the maximum amount of tokens that can be received for each of the supported peer chains + - **Sending Limits**: The maximum amount of tokens that can be sent from the home chain. + - **Receiving Limits**: The maximum amount of tokens that can be received for each of the supported peer chains. Enter a new value to adjust limits and click **Update**. The changes will take effect immediately. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp) ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/installation/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Installation -description: Learn how to Install Wormhole’s Native Token Transfers (NTT) framework, a flexible and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- - -# Install the Native Token Transfers CLI - -In this video, the Wormhole team walks you through installing the [Native Token Transfers (NTT) CLI](https://github.com/wormhole-foundation/native-token-transfers/tree/main/cli){target=\_blank}. You’ll see a practical demonstration of running commands, verifying your installation, and addressing common issues that might arise. If you prefer to follow written instructions or want a quick reference for each step, scroll down for the detailed installation guide. - -To start using the NTT CLI, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. - -
- -## Install NTT CLI - -The fastest way to deploy Native Token Transfers (NTT) is using the NTT CLI. As prerequisites, ensure you have the following installed: - -- Install [Bun](https://bun.sh/docs/installation){target=\_blank} - -Follow these steps to install the NTT CLI: - -1. Run the installation command in your terminal: - - ```bash - curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash - ``` - -2. Verify the NTT CLI is installed: - - ```bash - ntt --version - ``` - -3. Once installed, check out the available [NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/){target=\_blank} to start using the CLI - -## Update NTT CLI - -To update an existing NTT CLI installation, run the following command in your terminal: - -```bash -ntt update -``` - -NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. - -For local development, you can update your CLI version from a specific branch or install from a local path. - -To install from a specific branch, run: - -```bash -ntt update --branch foo -``` - -To install locally, run: -```bash -ntt update --path path/to/ntt/repo -``` - -Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. - -## Where to Go Next - -
- - -- :octicons-tools-16:{ .lg .middle } **Deploy to EVM Chains** - - --- - - Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to EVM chains](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) - -- :octicons-tools-16:{ .lg .middle } **Deploy to Solana** - - --- - - Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to Solana](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) - -
+![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp) --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/post-deployment/ --- BEGIN CONTENT --- --- title: Native Token Transfers Post Deployment @@ -1492,9 +1417,9 @@ categories: NTT, Transfer To offer the best user experience and ensure the most robust deployment, Wormhole contributors recommend the following after you have deployed Native Token Transfers (NTT): - Implement a robust testing plan for your multichain token before launching -- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/build/transfers/native-token-transfers/configuration/){target=\_blank} for more details on ownership and rate limits -- Consider a streamlined, customizable frontend such as [Wormhole Connect](/docs/build/transfers/connect/){target=\_blank} for an optimized user experience -- Alternatively, the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} allows for a direct integration into your infrastructure +- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} for more details on ownership and rate limits +- Consider a streamlined, customizable frontend such as [Connect](/docs/products/connect/overview/){target=\_blank} for an optimized user experience +- Alternatively, the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} allows for a direct integration into your infrastructure - Ensure ecosystem actors such as block explorers, automated security tools (such as BlockAid and Blowfish), and wallets (such as MetaMask, Backpack, and Phantom) are aware of your multichain deployment and that it is labeled appropriately - Monitor and maintain your multichain deployment @@ -1504,6 +1429,20 @@ By default, NTT transfers to Solana require manual relaying, meaning that after This step ensures that tokens are properly minted or unlocked on Solana and prevents unauthorized claims. +## Post-Deployment Settings + +The following table outlines post-deployment settings available on the NTT Manager contract. These allow you to update roles, pause activity, and adjust transfer limits—useful for upgrades, incident response, or protocol tuning after initial deployment. + +| Setting | Effect | +|-------------------------|------------------------------------------| +| `pause` | Pauses the manager | +| `unpause` | Unpauses the manager | +| `setOwner` | Changes the manager owner | +| `setPauser` | Changes the pauser role | +| `setOutboundLimit` | Sets outbound transfer limit | +| `setInboundLimit` | Sets inbound transfer limit (per chain) | +| `setTransceiverPauser ` | Changes pauser for a transceiver | + ## Where to Go Next
@@ -1512,7 +1451,7 @@ This step ensures that tokens are properly minted or unlocked on Solana and prev --- - Check out an example project that uses a Vite-React TypeScript application and integrates it with Wormhole Connect, a customizable widget for cross-chain asset transfers. + Check out an example project that uses a Vite-React TypeScript application and integrates it with Connect, a customizable widget for cross-chain asset transfers. [:custom-arrow: Explore the NTT Connect demo](https://github.com/wormhole-foundation/demo-ntt-connect) @@ -1527,7 +1466,7 @@ This step ensures that tokens are properly minted or unlocked on Solana and prev
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/troubleshoot/ --- BEGIN CONTENT --- --- title: Troubleshooting NTT Deployment @@ -1535,19 +1474,19 @@ description: Resolve common issues in NTT deployment with this troubleshooting g categories: NTT, Transfer --- -# Troubleshooting NTT Deployment +# Troubleshoot Your NTT Deployment If you encounter issues during the NTT deployment process, check the following common points: -- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#install-dependencies){target=\_blank} +- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/products/native-token-transfers/guides/deploy-to-solana/#install-dependencies){target=\_blank} - [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** - [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** - **Token compliance on EVM** - verify that your token is an ERC20 token on the EVM chain - **Mint authority transfer** - - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section - - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details -- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#configure-ntt){target=\_blank} section -- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#configure-ntt){target=\_blank} + - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/products/native-token-transfers/guides/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section + - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/products/native-token-transfers/guides/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details +- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/products/native-token-transfers/guides/deploy-to-solana/#configure-ntt){target=\_blank} section +- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/products/native-token-transfers/guides/deploy-to-evm/#configure-ntt){target=\_blank} - **Docker environment based on Ubuntu 20.04 with all dependencies required for Wormhole NTT CLI development** - run `docker compose up -d` to start the container in your terminal from the directory containing the `docker-compose.yml` file ???- interface "Dockerfile" @@ -1636,147 +1575,166 @@ If you encounter issues during the NTT deployment process, check the following c ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/faqs/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/overview/ --- BEGIN CONTENT --- --- -title: Native Token Transfers FAQs -description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +title: Native Token Transfers Overview +description: With Native Token Transfers, you can directly transfer a blockchain's native assets across various connected networks. categories: NTT, Transfer --- -# Wormhole NTT FAQs +## Native Token Transfers Overview -## Do you have an example of how cross-chain lending can be implemented using Wormhole? +Native Token Transfers (NTT) provides an adaptable framework for transferring your native tokens across different blockchains. Unlike traditional wrapped assets, NTT maintains your token's native properties on every chain. This ensures that you retain complete control over crucial aspects, such as metadata, ownership, upgradeability, and custom features. -Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. +## Key Features -Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/learn/transfers/native-token-transfers/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. +- **Control and customization**: Ensure ownership and configurable access controls, permissions, and thresholds, preventing unauthorized calls. +- **Advanced rate limiting**: Set rate limits per chain and period to prevent abuse, manage network congestion, and control deployments. +- **Global accountant**: Ensures the amount burned and transferred on chains never exceeds the amount of tokens minted. +- **No wrapped tokens**: Tokens are used directly within their native ecosystem, eliminating intermediary transfer steps. -## What causes the "No protocols registered for Evm" error in Wormhole SDK? -This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. +## Deployment Models -To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: +NTT offers two operational modes for your existing tokens: -```rust -import '@wormhole-foundation/sdk-evm-ntt'; -``` +- **Hub-and-spoke**: Locks tokens on a central "hub" chain and mints equivalents on "spoke" chains, maintaining the total supply on the hub. It's ideal for integrating existing tokens onto new blockchains without altering their original contracts. +- **Burn-and-mint**: Burns tokens on the source chain and mints new ones on the destination, distributing the total supply across multiple chains. It's best suited for new token deployments or projects willing to upgrade existing contracts for a truly native multichain token. -By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. +## Supported Token Standards -## How can I transfer ownership of NTT to a multisig? +Native Token Transfers (NTT) primarily support ERC-20 tokens, the most widely used standard for fungible assets on Ethereum and other EVM-compatible chains, including ERC-20 Burnable tokens, which can be burned on the source chain during cross-chain transfers when required. It also supports fungible SPL tokens on Solana for secure cross-chain transfers. -Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. +The NttManager is a contract that oversees the secure and reliable transfer of native tokens across supported blockchains. It leverages the standard IERC20 interface and OpenZeppelin’s SafeERC20 library to interact with these tokens securely across chains. -1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) -2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer -3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) +NTT does not currently support token standards like ERC-721 (non-fungible tokens), ERC-1155 (a multi-token standard), or SPL-based tokens, such as Metaplex NFTs. Support is currently limited to ERC-20 tokens. -For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. +## Deployment Process -## How can I specify a custom RPC for NTT? +Here's a breakdown of the key steps involved when deploying NTT: -To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. +- **Prepare tokens**: Ensure your ERC-20 or SPL tokens are ready. +- **Choose deployment model**: Choose your cross-chain token model: either burn-and-mint or hub-and-spoke. +- **Choose deployment tool**: Use the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for EVM chains only) or the [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank}. +- **Initialization**: Specify target chains and token details, and set up your CLI environment if using it. +- **Deploy contracts**: Deploy NTT Manager contracts to all selected chains, confirming transactions and covering gas fees. +- **Finalize configurations**: Grant minting authority, configure rate limits, establish peer manager connections, and assign administrative roles. +- **Monitor and maintain**: Verify deployment, monitor total supply with the [Global Accountant](/docs/products/native-token-transfers/concepts/security/#global-accountant){target=\_blank}, and adjust configurations as needed. -Below’s an example of how the `overrides.json` file should be structured: +## Use Cases -???- code "`overrides.json`" - ```json - { - "chains": { - "Bsc": { - "rpc": "http://127.0.0.1:8545" - }, - "Sepolia": { - "rpc": "http://127.0.0.1:8546" - }, - "Solana": { - "rpc": "http://127.0.0.1:8899" - } - } - } - ``` +- **Cross-Chain Swaps and Liquidity Aggregation** -## How can I redeem tokens if NTT rate limits block them on the target chain? + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transmits native assets across chains. + - [**Connect**](/docs/products/connect/overview/): Manages user-friendly asset transfers. + - [**Queries**](/docs/products/queries/overview/): Acquires real-time prices for optimal trade execution. -If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. +- **Borrowing and Lending Across Chains** -To resolve this: + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Moves collateral as native assets. + - [**Messaging**](/docs/products/messaging/overview/): Propagates loan requests and liquidations across chains. + - [**Queries**](/docs/products/queries/overview/): Retrieves interest rates and asset prices in real-time. -1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed -2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain +- **Gas Abstraction** -In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Facilitates native token conversion for gas payments. + - [**Messaging**](/docs/products/messaging/overview/): Sends gas fee payments across chains. -## What are the challenges of deploying NTT to non-EVM chains? +- **Cross-Chain Payment Widgets** -NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Ensures direct, native asset transfers. + - [**Connect**](/docs/products/connect/overview/): Facilitates seamless payments in various tokens. -## Does the NTT manager function as an escrow account for a hub chain? +- **Cross-Chain Staking** -Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transfers staked assets natively between networks. + - [**Messaging**](/docs/products/messaging/overview/): Moves staking rewards and governance signals across chains. -## Which functions or events does Connect rely on for NTT integration? +## Next Steps -Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: +Follow these steps to get started with NTT: -- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain -- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion +[timeline(wormhole-docs/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json)] +--- END CONTENT --- -These functions ensure Connect can handle token transfers and manage chain-rate limits. +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/cli-commands/ +--- BEGIN CONTENT --- +--- +title: NTT CLI Commands +description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +categories: NTT, Transfer +--- -## How does the relayer contract determine which transceiver to call? +# NTT CLI Commands -The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. +## Introduction -## How do I create a verifier or transceiver? +The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. -To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. +If you haven't installed the NTT CLI yet, follow the [NTT Installation](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank} instructions to set it up before proceeding. -For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. +## Table of Commands -## Can I use Hetzner for the NTT deployment? +The following table lists the available NTT CLI commands, descriptions, and examples. -No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. +To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. -## How can I transfer tokens with NTT with an additional payload? +### General Commands -You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. +| Command | Description | Example | +|-----------------------------------------|--------------------------------------------------------|--------------------------------------------------------------------| +| `ntt update` | update the NTT CLI | `ntt update` | +| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | +| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest` | +| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0` | +| `ntt clone
` | initialize a deployment file from an existing contract | `ntt clone Mainnet Solana Sol5678...` | +| `ntt init ` | initialize a deployment file | `ntt init devnet` | +| `ntt pull` | pull the remote configuration | `ntt pull` | +| `ntt push` | push the local configuration | `ntt push` | +| `ntt status` | check the status of the deployment | `ntt status` | -- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message -- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message +### Configuration Commands -!!!Important - You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. +| Command | Description | Example | +|----------------------------------------------|-----------------------------------------|------------------------------------------------| +| `ntt config set-chain ` | set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key` | +| `ntt config unset-chain ` | unset a configuration value for a chain | `ntt config unset-chain Ethereum scan_api_key` | +| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key` | -## Why use NTT over xERC20? +### Solana Commands -Shortcomings of xERC20: +| Command | Description | Example | +|------------------------------------------------|----------------------------------------------------------|-------------------------------------------------| +| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json` | +| `ntt solana token-authority ` | print the token authority address for a given program ID | `ntt solana token-authority Sol1234...` | +| `ntt solana ata ` | print the token authority address for a given program ID | `ntt solana ata Mint123... Owner123... token22` | -- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach -- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies -- **No access control** - there are no built-in access controls for managing token transfers securely -- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security -- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups +## Where to Go Next -While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. +
-## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? -To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. +- :octicons-gear-16:{ .lg .middle } **Configure NTT** -## Is there a way to use NTT tokens with chains that don't currently support NTT? + --- -Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. For example: + Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) -- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism -- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT + [:custom-arrow: Configure your NTT deployment](/docs/products/native-token-transfers/configuration/access-control/) -This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. +- :octicons-question-16:{ .lg .middle } **NTT FAQs** + + --- + + Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. + + [:custom-arrow: Check out the FAQs](/docs/products/native-token-transfers/faqs/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/managers-transceivers/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/managers-transceivers/ --- BEGIN CONTENT --- --- title: Managers and Transceivers @@ -2088,2090 +2046,2485 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary +# Get Started with Messaging -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Chain ID +## Prerequisites -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +Before you begin, ensure you have the following: -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -## Consistency Level +## Configure Your Messaging Environment -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a directory and initialize a Node.js project: -## Delivery Provider + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Emitter + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Finality + ```bash + npx tsc --init + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + Make sure your `tsconfig.json` includes the following settings: -## Guardian + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Guardian Network + ```bash + npm install @wormhole-foundation/sdk + ``` -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. Create a new file named `main.ts`: -## Guardian Set + ```bash + touch main.ts + ``` -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Heartbeat + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -## Observation + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -## Relayer + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -A relayer is any process that delivers VAAs to a destination. +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -## Sequence + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +2. Run the script using the following command: -## Spy + ```bash + npx tsx main.ts + ``` -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-## VAA +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -## Validator +## Next Steps -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Infrastructure Components - -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. - -## Get Started - -Start here for an overview of Wormhole architecture components and security mechanisms: - -
+# Get Started with Core Contracts -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Introduction - --- +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -- :octicons-book-16:{ .lg .middle } **Security** +## Prerequisites - --- +To interact with the Wormhole Core Contract, you'll need the following: - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - [:custom-arrow: Learn About Security](/docs/learn/security/) +## How to Interact with Core Contracts -
+Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -## Explore Components +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +### Sending Messages -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -## Next Steps +=== "EVM" -
+ The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -- :octicons-book-16:{ .lg .middle } **Messaging Components** + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` - --- + ??? interface "Parameters" - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - --- + --- - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + ??? interface "Returns" -
---- END CONTENT --- + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -# Architecture +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -## Overview +// Check fee and send parameters -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: +=== "Solana" - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -## On-Chain Components + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + ??? interface "Parameters" -## Off-Chain Components + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -## Next Steps + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -
+ For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -- :octicons-book-16:{ .lg .middle } **Core Contracts** + ??? child "Type `PostMessage<'info>`" - --- + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + `batch_id` ++"u32"++ + + An identifier for the message batch. - --- + --- - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + --- -
---- END CONTENT --- + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -# Core Contracts + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -## Introduction + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -## Key Functions + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -Key functions of the Wormhole Core Contract include the following: +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -## How the Core Contract Works +### Receiving Messages -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. +The way a message is received and handled depends on the environment. -The following describes the role of the Wormhole Core Contract in message transfers: +=== "EVM" -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -### Message Submission + ??? interface "Parameters" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + ??? interface "Returns" -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -### Message Reception + ??? child "Struct `VM`" -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. - -## Multicast - -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. - -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -## Next Steps + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -
+ ??? interface "Example" -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); - --- + // Perform safety checks here - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + // Your custom application logic here +} + ``` -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - --- +=== "Solana" - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + Retrieve the raw message data: -
---- END CONTENT --- + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Example" -## Guardian + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -Guardians fulfill their role in the messaging protocol as follows: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +#### Validating the Emitter -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -## Guardian Network +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -The Guardian Network is designed to help Wormhole deliver on five key principles: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -The following sections explore each principle in detail. +await tx.wait(); +``` -### Decentralization +#### Additional Checks -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Two common approaches to decentralization have notable limitations: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +## Source Code References -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -To answer that, consider these key constraints and design decisions: +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +# Wormhole Relayer -### Modularity +## Introduction -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -### Chain Agnosticism +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +## Get Started with the Wormhole Relayer -### Scalability +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +### Wormhole Relayer Interfaces -### Upgradeable +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -Wormhole is designed to adapt and evolve in the following ways: +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +## Interact with the Wormhole Relayer -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -## Next Steps +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -
+To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -- :octicons-book-16:{ .lg .middle } **Relayers** +Your initial set up should resemble the following: - --- +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +contract Example { + IWormholeRelayer public wormholeRelayer; -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` - --- +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +### Send a Message - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -
---- END CONTENT --- +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -# Relayers +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -There are three primary types of relayers discussed: +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +### Receive a Message -## Fundamentals +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Key characteristics of VAAs include: +## Delivery Guarantees -- Public emission from the Guardian Network +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- Authentication through signatures from the Guardian Network +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- Verifiability by any entity or any Wormhole Core Contract +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +## Delivery Statuses -Keep in mind the following security considerations around relayers: +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -## Client-Side Relaying +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -### Key Features +## Other Considerations -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -### Implementation +## Track the Progress of Messages with the Wormhole CLI -Users themselves carry out the three steps of the cross-chain process: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -1. Perform an action on chain A +=== "Mainnet" -2. Retrieve the resulting VAA from the Guardian Network + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -3. Perform an action on chain B using the VAA +=== "Testnet" -### Considerations + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -- Users must sign all required transactions with their own wallet +## Step-by-Step Tutorial -- Users must have funds to pay the transaction fees on every chain involved +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -- The user experience may be cumbersome due to the manual steps involved +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -## Custom Relayers +# Messaging Overview -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +## Key Features -### Key Features +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## How It Works -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +The messaging flow consists of several core components: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -### Implementation +## Use Cases -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Considerations +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- Development work and hosting of relayers are required +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +- **Gas Abstraction** -## Wormhole Relayers + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +- **Bridging Intent Library** -### Key Features + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -### Implementation +## Next Steps -The Wormhole relayer integration involves two key steps: +Follow these steps to work with Wormhole Messaging: -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Considerations +# Products -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- All computations are performed on-chain +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -- Potentially less gas-efficient compared to custom relayers +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +## Transfer Products -- Support may not be available for all chains +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -## Next Steps +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-- :octicons-book-16:{ .lg .middle } **Spy** +::spantable:: - --- +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +::end-spantable:: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +
-- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - --- +
- Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +## Bridging UI -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - --- +## Real-time Data - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Multichain Governance -
+[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Spy - -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +# Glossary -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +## Chain ID -## Key Features +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -## Integrator Use Case +## Consistency Level -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +## Delivery Provider -## Observable Message Categories +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -A Spy can access the following categories of messages shared over the gossip protocol: +## Emitter -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +## Finality -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +## Guardian -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +## Guardian Network -## Additional Resources +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -
+## Guardian Set -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - --- +## Heartbeat - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +## Observation - --- +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +## Relayer - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +A relayer is any process that delivers VAAs to a destination. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +## Sequence - --- +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +## Spy - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. -
+## VAA -## Next Steps +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -
+## Validator -- :octicons-code-16:{ .lg .middle } **Run a Spy** +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- - --- +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +# Architecture - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +## Overview -- :octicons-code-16:{ .lg .middle } **Use Queries** +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. - --- +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ ---- BEGIN CONTENT --- ---- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. -categories: Basics ---- - -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. - -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. - -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. - -## VAA Format - -The basic VAA consists of header and body components described as follows: - -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - Where each `signature` is: + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## On-Chain Components -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +## Off-Chain Components -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Consistency and Finality +## Next Steps -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +
-Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- :octicons-book-16:{ .lg .middle } **Core Contracts** -## Signatures + --- -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -## Payload Types + --- -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -### Token Transfer + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +
+--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# The Wormhole Ecosystem -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Ecosystem Overview -### Attestation +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -The message format for token attestation is as follows: +## Bringing It All Together: Interoperability in Action -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. -#### Attestation Tips +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -Be aware of the following considerations when working with attestations: +## Next Steps -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +# Core Contracts -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Introduction -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer with Message +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +## Key Functions -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Key functions of the Wormhole Core Contract include the following: -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## How the Core Contract Works -### Governance +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +The following describes the role of the Wormhole Core Contract in message transfers: -#### Action Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Message Submission -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -#### Actions +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +### Message Reception -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Lifetime of a Message +## Multicast -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Introduction to Wormhole +## Guardian -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Guardians fulfill their role in the messaging protocol as follows: -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +## Guardian Network -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +The Guardian Network is designed to help Wormhole deliver on five key principles: -## What Problems Does Wormhole Solve? +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following sections explore each principle in detail. -Critical problems Wormhole addresses include: +### Decentralization -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -## What Does Wormhole Offer? +Two common approaches to decentralization have notable limitations: -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -## What Isn't Wormhole? +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +To answer that, consider these key constraints and design decisions: -## Use Cases of Wormhole +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -Consider the following examples of potential applications enabled by Wormhole: +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +### Modularity -## Explore +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -Discover more about the Wormhole ecosystem, components, and protocols: +### Chain Agnosticism -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -## Demos - -Demos offer more realistic implementations than tutorials: - -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs - - - -!!! note - Wormhole Integration Complete? - - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! - - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** - -## Supported Blockchains - -Wormhole supports a growing number of blockchains. - -text/supported-networks.md ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- - -# Security - -## Core Security Assumptions - -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. - -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem - -In summary: - -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit - -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. - -## Guardian Network - -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. - -### Governance - -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. - -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. - -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +### Scalability -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -Via governance, the Guardians can: +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +### Upgradeable -## Monitoring +Wormhole is designed to adapt and evolve in the following ways: -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -Guardians monitor: +## Next Steps -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +
-## Asset Layer Protections +- :octicons-book-16:{ .lg .middle } **Relayers** -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. + --- -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -## Open Source +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -Wormhole builds in the open and is always open source. + --- -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. -## Audits + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +
+--- END CONTENT --- -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ +--- BEGIN CONTENT --- +--- +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +categories: Basics +--- -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +# Relayers -## Bug Bounties +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +There are three primary types of relayers discussed: -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -## Learn More +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +## Fundamentals -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics ---- +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -# Get Started with Core Contracts +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -## Introduction +Key characteristics of VAAs include: -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +- Public emission from the Guardian Network -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +- Authentication through signatures from the Guardian Network -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +- Verifiability by any entity or any Wormhole Core Contract -## Prerequisites +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -To interact with the Wormhole Core Contract, you'll need the following: +Keep in mind the following security considerations around relayers: -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## How to Interact with Core Contracts +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +## Client-Side Relaying -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -### Sending Messages +### Key Features -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -=== "EVM" +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +### Implementation - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +Users themselves carry out the three steps of the cross-chain process: - ??? interface "Parameters" +1. Perform an action on chain A - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +2. Retrieve the resulting VAA from the Guardian Network - --- +3. Perform an action on chain B using the VAA - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +### Considerations - --- +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- Users must sign all required transactions with their own wallet - ??? interface "Returns" +- Users must have funds to pay the transaction fees on every chain involved - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +- The user experience may be cumbersome due to the manual steps involved - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +## Custom Relayers -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -// Check fee and send parameters +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +### Key Features -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -=== "Solana" +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +### Implementation - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - ??? interface "Parameters" +### Considerations - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +- Development work and hosting of relayers are required - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - ??? child "Type `PostMessage<'info>`" +## Wormhole Relayers - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +### Key Features - --- +- **Lower operational costs** - no need to develop, host, or maintain individual relayers - `batch_id` ++"u32"++ - - An identifier for the message batch. +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - --- +### Implementation - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +The Wormhole relayer integration involves two key steps: - --- +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +### Considerations - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +- All computations are performed on-chain -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +- Potentially less gas-efficient compared to custom relayers -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- Support may not be available for all chains -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +## Next Steps -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +
-### Receiving Messages +- :octicons-book-16:{ .lg .middle } **Spy** -The way a message is received and handled depends on the environment. + --- -=== "EVM" + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - ??? interface "Parameters" + --- - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ??? interface "Returns" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - ??? child "Struct `VM`" + --- - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- +
+--- END CONTENT --- - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - ??? interface "Example" +# Spy - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - // Perform safety checks here +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - // Your custom application logic here -} - ``` +## Key Features - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure -=== "Solana" +## Integrator Use Case - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - Retrieve the raw message data: +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +## Observable Message Categories - ??? interface "Example" +A Spy can access the following categories of messages shared over the gossip protocol: - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -#### Validating the Emitter + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +## Additional Resources -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +
-```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -await tx.wait(); -``` + --- -#### Additional Checks + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + --- -## Source Code References + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + --- -# Wormhole Relayer + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -## Introduction + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +
-This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +## Next Steps -## Get Started with the Wormhole Relayer +
-Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +- :octicons-code-16:{ .lg .middle } **Run a Spy** -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. + --- -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+ Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -### Wormhole Relayer Interfaces + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +- :octicons-code-16:{ .lg .middle } **Use Queries** -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + --- -## Interact with the Wormhole Relayer + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. +
+--- END CONTENT --- -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -Your initial set up should resemble the following: +# Verified Action Approvals -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -contract Example { - IWormholeRelayer public wormholeRelayer; +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -### Send a Message +## VAA Format -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The basic VAA consists of header and body components described as follows: -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. + Where each `signature` is: -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +## Consistency and Finality -### Receive a Message +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +## Signatures -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -## Delivery Guarantees +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +## Payload Types -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -## Delivery Statuses +### Token Transfer -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Transferring tokens from the sending chain to the destination chain requires the following steps: -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -## Other Considerations +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +### Attestation -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -## Track the Progress of Messages with the Wormhole CLI +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +The message format for token attestation is as follows: -=== "Mainnet" +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +#### Attestation Tips -=== "Testnet" +Be aware of the following considerations when working with attestations: - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -## Step-by-Step Tutorial +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -# Products +### Token Transfer with Message -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -## Transfer Products +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +### Governance -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -
+#### Action Structure -::spantable:: +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -::end-spantable:: +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -
+```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +#### Actions -## Bridging UI +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -## Real-time Data +## Lifetime of a Message -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -## Multichain Governance +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -# Wormhole Use Cases +## Next Steps -
-
+
-## Cross-Chain Swaps and Liquidity Aggregation +- :octicons-book-16:{ .lg .middle } **Guardians** -Enable seamless swaps between chains with real-time liquidity routing. + --- -
-
+ Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -🛠 **Wormhole products used:** + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + --- -
-
+ Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -
-
+
+--- END CONTENT --- -## Borrowing and Lending Across Chains +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -Let users borrow assets on one chain using collateral from another. +# Introduction to Wormhole -
-
+In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -🛠 **Wormhole products used:** +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -
-
+!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
-
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -## Real-Time Price Feeds and Trading Strategies +## What Problems Does Wormhole Solve? -Fetch price feeds across multiple chains for DeFi applications. +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -
-
+Critical problems Wormhole addresses include: -🛠 **Wormhole products used:** +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +## What Does Wormhole Offer? -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -
-
+- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. +## What Isn't Wormhole? -
-
+- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -## Asset Movement Between Bitcoin and Other Chains +## Use Cases of Wormhole -Enable direct BTC transfers without wrapped assets. +Consider the following examples of potential applications enabled by Wormhole: -
-
+- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -🛠 **Wormhole products used:** +## Explore -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Discover more about the Wormhole ecosystem, components, and protocols: -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -
-
+Demos offer more realistic implementations than tutorials: -## Decentralized Social Platforms +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -Enable seamless communication and asset transfer across decentralized social networks. + -🛠 **Wormhole products used:** +!!! note + Wormhole Integration Complete? -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -
-
+## Supported Networks by Product +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -## Memecoin Launchpads +# Security -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -🛠 **Wormhole products used:** +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +In summary: -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -
-
+Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -## Cross-Chain Perpetuals +### Governance -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -🛠 **Wormhole products used:** +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +Via governance, the Guardians can: -
-
+- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -## Gas Abstraction +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: -🛠 **Wormhole products used:** +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +## Asset Layer Protections -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -
-
+## Open Source -## Bridging Intent Library +Wormhole builds in the open and is always open source. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -
-
+## Audits -🛠 **Wormhole products used:** +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -
-
+## Bug Bounties +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -
-
+Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -## Multichain Prediction Markets +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -
-
+## Learn More -🛠 **Wormhole products used:** +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +# Get Started with the Solidity SDK -
-
+The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. +## Install the SDK -
-
+Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -## Cross-Chain Payment Widgets +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +## Key Components -
-
+The following key components and features work together to make your on-chain Wormhole integration easier to build. -🛠 **Wormhole products used:** +??? interface "Base contracts" -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers + Leverage base contracts to send and receive messages and tokens. -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -
-
+??? interface "Interfaces" + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -
-
+ - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -## Oracle Networks +??? interface "Constants" -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -
-
+ - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -🛠 **Wormhole products used:** +## Example Usage -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +### Prerequisites +Before you begin, ensure you have the following: -
-
+- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer +### Set Up a Project -
-
+Follow these steps to prepare your development environment: -## Cross-Chain Staking +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -Enable users to stake assets on one chain while earning rewards or securing networks on another. + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -
-
+2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -🛠 **Wormhole products used:** + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -
-
---- END CONTENT --- + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -## Reference Concepts [shared: true] + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` ---- + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -## List of shared concept pages: +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. +## Use Contracts to Transfer USDC -## Full content for shared concepts: +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- + ```bash + touch script/transfer.ts + ``` -# Reference +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -## Get Started +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -
+ // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - --- + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); - --- + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -4294,7 +4647,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -4349,7 +4702,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -4565,262 +4918,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -4832,7 +5019,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -5007,7 +5194,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -5088,4 +5275,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-queries.txt b/llms-files/llms-queries.txt index 9b10f8a79..501df49a3 100644 --- a/llms-files/llms-queries.txt +++ b/llms-files/llms-queries.txt @@ -13,57 +13,16 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/overview.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/use-queries.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/guides/use-queries.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-methods.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-networks.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/queries/ ---- BEGIN CONTENT --- ---- -title: Wormhole Queries -description: Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. -categories: Queries ---- - -# Queries - -## Get Started - -Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. - -
- -- :octicons-book-16:{ .lg .middle } **Overview** - - --- - - Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST API endpoint, enabling secure cross-chain interactions and verifications. - - [:custom-arrow: Learn about Queries](/docs/build/queries/overview/) - -- :octicons-code-16:{ .lg .middle } **Use Queries** - - --- - - Explore a simple demo of interacting with Wormhole Queries using an `eth_call` request to query the supply of wETH on Ethereum using a Wormhole query. - - [:custom-arrow: Get hands-on](/docs/build/queries/use-queries/) - -- :octicons-book-16:{ .lg .middle } **Query FAQs** - - --- - - Explore frequently asked questions about Wormhole Queries. - - [:custom-arrow: Check out the FAQs](/docs/build/queries/faqs/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/queries/faqs/ +Doc-Content: https://wormhole.com/docs/products/queries/faqs/ --- BEGIN CONTENT --- --- title: Queries FAQs @@ -88,7 +47,7 @@ categories: Queries ## Are there any query examples? -Certainly. You can find a complete guide on the [Use Queries page](/docs/build/queries/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: +Certainly. You can find a complete guide on the [Use Queries page](/docs/products/queries/guides/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: - [Basic Example Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} - [Solana Stake Pool Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} @@ -101,7 +60,7 @@ The Guardian node calculates an ECDSA signature using [`Sign` function of the cr ```keccak256("query_response_0000000000000000000|"+keccak256(responseBytes))``` -See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_key.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. +See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_signer.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. !!! note If you are used to `ecrecover` you will notice that the `v` byte is `0` or `1` as opposed to `27` or `28`. The `signaturesToEvmStruct` method in the [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} accounts for this as well as structuring the signatures into an `IWormhole.SignatureStruct[]`. @@ -117,111 +76,161 @@ It is also important to note that the proxies don't impact the verifiability of Wormhole Queries provides on-demand, attested, on-chain, verifiable RPC results. Each Guardian independently executes the specified query and returns the result and their signature. The proxy handles aggregating the results and signatures, giving you a single result (all within one REST call) with a quorum of signatures suitable for on-chain submission, parsing, and verification using one of our examples or SDKs. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/queries/overview/ +Doc-Content: https://wormhole.com/docs/products/queries/get-started/ --- BEGIN CONTENT --- --- -title: Queries Overview -description: Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST endpoint, enabling secure cross-chain interactions and verifications. +title: Get Started with Queries +description: Follow this guide to run your first multichain, verifiable query with the Wormhole Queries SDK and Proxy, using eth_call to fetch token metadata. categories: Queries --- -# Queries Overview {: #queries-overview } - -Wormhole Guardians, who run full nodes for various connected chains, facilitate a new cross-chain query service that allows for on-demand attested responses to queries, bypassing the inefficiencies of traditional transaction-based data retrieval. This method is faster and cost-effective, eliminating the need for gas payments and transaction finality wait times. +# Get Started with Queries -!!! note - Queries are currently in closed beta, though you can start developing today. Check out [Use Queries](/docs/build/queries/use-queries/){target=\_blank} and reach out to [Join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. - -Wormhole Queries offers on-demand access to Guardian-attested on-chain data. The current implementation provides integrators with a simple REST endpoint to initiate an off-chain request via a proxy. The proxy then forwards the request to the Guardians and gathers a quorum of responses. The result returns the encoded response, including the request details and the Guardian signatures. The request validation performed by the query module includes a three step process that involves verifying the signature to ensure it has the correct prefix, confirming that the signer is authorized to execute query requests, and validating the legitimacy of all per-chain requests contained in the query. You can read more about Queries in the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank}. - -## The Flow of a Query {: #the-flow-of-a-query} +## Introduction -The general overview of a query's flow is as follows: an off-chain process sends HTTPS query requests to a Query Proxy, which validates and forwards them to the Guardians; these Guardians independently validate, sign, and return the response, with the entire process typically taking less than a second. +[Queries](/docs/products/queries/overview) lets you fetch on-chain data from supported blockchains using `eth_call`-style requests without submitting transactions or paying gas. The Guardian network signs the result, making it verifiable and suitable for use on-chain. -![The architecture flow of a query](/docs/images/build/queries/overview/overview-1.webp) +This guide walks you through requesting an API key, constructing your first query using the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, and decoding the result. -The step-by-step flow of a query is as follows: +## Prerequisites -1. An off-chain process initiates a query request via HTTPS to the query proxy (or Query Server) -2. The query proxy validates the request and forwards it to the Guardians via a gossip network -3. The Guardians independently validate the request, make the requisite RPC calls, verify the results, sign, and gossip a response back to the Query Proxy -4. The Query Proxy aggregates the results and returns a response when it reaches a quorum of two-thirds or more of the current Guardian set - the exact quorum requirements as the core bridge -5. The off-chain process can then submit these requests to an on-chain contract which should verify the signatures and validate the request before processing the result +Before you begin, make sure you have the following: -In this flow, the Query Proxy is a permissioned but trustless part of the protocol. In most cases, this entire process takes less than one second. If a request is invalid or cannot be processed by the Guardians, they will retry for up to one minute before timing out. Requests can be batched to have the Guardians make multiple calls to multiple networks. This can further reduce overhead for processing query responses on-chain. Up to 255 queries can be batched together, with certain types allowing for batching themselves. + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - A basic understanding of JavaScript or TypeScript + - An RPC endpoint for a supported chain (e.g., Ethereum Sepolia) + - A Wormhole Queries API key -## Supported Query Types {: #supported-query-types} +## Request an API Key -There are currently five supported types of queries. See [the white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank} for more details on each. +Wormhole Queries is in closed beta, but you can start building today. -### eth_call {: #eth-call} +To interact with the system, you will use the Query Proxy. This hosted service receives your query, routes it to the appropriate chain, and returns a signed, verifiable response from the Guardian network. The Query Proxy allows you to fetch on-chain data without infrastructure overhead. -This query type is effectively an equivalent of [eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a block specified by number or hash. +To request access, join the beta by filling out the [access form](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. Once approved, you will receive an API key via email. -Calls are batched to allow specifying multiple calls (even to multiple contracts) against the same block. These calls are included in a single batch RPC call, simplifying on-chain verification. Up to 255 calls may be batched in an single `eth_call` query. +## Construct a Query and Decode the Response -The result contains the specified block number, hash, timestamp, and the call result. +Using the Wormhole Query Proxy, you will write a lightweight script to query a token contract's `name()` on Ethereum Sepolia. The response is signed by the Guardian network and locally decoded for use in your application. -### eth_call By Timestamp {: #eth-call-by-timestamp} +1. Create a new directory for your script and initialize a Node.js project: -This query type is similar to `eth_call` but targets a timestamp instead of a specific `block_id`. This can be useful when forming requests based on uncorrelated data, such as requiring data from another chain based on the block timestamp of a given chain. + ```bash + mkdir queries + cd queries + npm init -y + ``` -The result also contains the target and block details with the following enforced conditions: `target_block.timestamp <= target_time < following_block.timestamp` and `following_block_num - 1 == target_block_num`. +2. Add the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, [Axios](https://www.npmjs.com/package/axios){target=\_blank}, [Web3](https://www.npmjs.com/package/web3){target=\_blank}, and helper tools: -### eth_call With Finality {: #eth-call-with-finality} + ```bash + npm install axios web3 @wormhole-foundation/wormhole-query-sdk + npm install -D tsx typescript + ``` -This query type is similar to `eth_call` but ensures that the specified block has reached the specified finality before returning the query results. The finality may be `finalized` or `safe.` Note that if a chain doesn't natively support the `safe` tag, this will be equivalent to `finalized.` +3. Add a new `query.ts` script where you will write and run your query logic: -### sol_account {: #sol_account} + ```bash + touch query.ts + ``` -This query is used to read data for one or more accounts on Solana, akin to [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank}. +4. Paste the following script into `query.ts` to build and submit a query to the token contract's `name()` function on Ethereum Sepolia, then decode the Guardian-signed response: -### sol_pda {: #sol_pda} + ```typescript + // Import the SDK types and helpers for making the query +import { + EthCallQueryRequest, + EthCallQueryResponse, + PerChainQueryRequest, + QueryRequest, + QueryResponse, +} from '@wormhole-foundation/wormhole-query-sdk'; +import axios from 'axios'; +import * as eth from 'web3'; -This query is used to read data for one or more [Program Derived Addresses(PDA)](https://www.anchor-lang.com/docs/pdas){target=\_blank} on Solana, akin to calling [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} on the result of `PublicKey.findProgramAddressSync(seeds, programId).` This query is helpful for times when you want to more generally read accounts owned by a program and verify the derivation on another chain, like how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. +// Define the endpoint and query parameters +const query_url = 'https://testnet.query.wormhole.com/v1/query'; +const rpc = 'https://ethereum-sepolia.rpc.subquery.network/public'; +const chain_id = 10002; // Sepolia (Wormhole chain ID) +const token = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'; // USDC contract +const data = '0x06fdde03'; // function selector for `name()` -## Supported Chains {: #supported-chains} +// Load your API key from environment variables +const apiKey = process.env.API_KEY; +if (!apiKey) throw new Error('API_KEY is not set in your environment'); -The following table provides expected support based on testing. However, the success of any given query is based on the success of the underlying call on each Guardian’s RPC node. +(async () => { + // Fetch the latest block number (required to anchor the query) + const latestBlock = ( + await axios.post(rpc, { + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 1, + jsonrpc: '2.0', + }) + ).data?.result?.number; -For example, many chains have implementations forked from [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which keeps 128 blocks of state in memory by default (without running in archive mode). While this is good for about 25 minutes of history on Ethereum Mainnet, it is only about three minutes on Optimism. While Guardian nodes can be expected to have access to recent state, there are currently no guarantees of how far back in history they have access to. + // Build the query targeting the token contract's name() function + const request = new QueryRequest(1, [ + new PerChainQueryRequest( + chain_id, + new EthCallQueryRequest(latestBlock, [{ to: token, data: data }]) + ), + ]); + const serialized = request.serialize(); + + // Send the query to the Wormhole Query Proxy + const response = await axios.post( + query_url, + { bytes: Buffer.from(serialized).toString('hex') }, + { headers: { 'X-API-Key': apiKey } } + ); -### Mainnet {: #mainnet} + // Decode the response returned by the Guardian network + const queryResponse = QueryResponse.from(response.data.bytes); + const chainResponse = queryResponse.responses[0] + .response as EthCallQueryResponse; + const name = eth.eth.abi.decodeParameter('string', chainResponse.results[0]); -| Chain | Wormhole Chain ID | eth_call | By Timestamp | With Finality | Expected History | -|:-------------:|:-----------------:|:--------:|:------------------:|:-------------:|:----------------:| -| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | -| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | -| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | -| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | -| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | -| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | -| Karura | 11 | ✅ | ✅ | ✅ | archive | -| Acala | 12 | ✅ | ✅ | ✅ | archive | -| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | -| Celo | 14 | ✅ | ℹ️ hints required\* | ✅ | 128 blocks | -| Moonbeam | 16 | ✅ | ℹ️ hints required\* | ✅ | 256 blocks | -| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | -| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | -| Base | 30 | ✅ | ✅ | ✅ | archive | + // Output the results + console.log('\n\nParsed chain response:'); + console.log(chainResponse); + console.log('\nToken name:', name); +})(); + ``` -\*`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. +5. Use your API key to execute the script: -## Next Steps {: #next-steps} + ```bash + API_KEY=INSERT_QUERIES_API_KEY npx tsx query.ts + ``` -Remember that Wormhole Queries are currently in beta. You can [register to join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to fully experiment with Wormhole Queries. +The expected output should be similar to this: + +
+API_KEY=123_456_789 npx tsx query.ts +Parsed chain response: +EthCallQueryResponse { +blockNumber: 8193548n, +blockHash: '0xef97290e043a530dd2cdf2d4c513397495029cdf2ef3e916746c837dadda51a8', +blockTime: 1745595132000000n, +results: [ '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000'] +} + +Token name: USDC + +
-Be sure to check out the [FAQs](/docs/build/queries/faqs/){target=\_blank} and the [Use Queries guide](/docs/build/queries/use-queries/){target=\_blank}. +## Next Steps -You can also check out the following examples of applications that make use of Wormhole Queries: +Now that you've successfully run your first verifiable query, you are ready to go deeper. Check out the following guides to build on what you've learned: -- [Basic demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} -- [Solana Stake Pool](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} -- [Solana Program Derived Address (PDA) / Token Account Balance](https://github.com/wormholelabs-xyz/example-queries-solana-pda){target=\_blank} -- [Solana Queries Verification](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} +- [**Query Solana**](https://github.com/wormhole-foundation/demo-queries-ts/blob/main/src/query_solana_stake_pool.ts){target=\_blank}: Try fetching Solana stake pools to see how cross-chain queries apply beyond EVM. +- [**Use Queries**](/docs/products/queries/guides/use-queries){target=\_blank}: Take a deeper look at the complete Queries lifecycle. +- **Browse the [Supported Networks](/docs/products/queries/reference/supported-networks){target=\_blank}**: See where Queries are supported. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/queries/use-queries/ +Doc-Content: https://wormhole.com/docs/products/queries/guides/use-queries/ --- BEGIN CONTENT --- --- title: Use Queries @@ -235,32 +244,6 @@ You can visit the [Example Queries Demo](https://wormholelabs-xyz.github.io/exam This guide covers using a simple `eth_call` request to get the total supply of WETH on Ethereum. -## RPC Basics - -Before digging into anything Queries-specific, this page will look at how to make an [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a public Ethereum RPC. Suppose you'd like to query the WETH contract for its total supply; before making a request, you need some information about the contract you want to call, including: - -- **To** - the contract to call. WETH is [0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2){target=\_blank} -- **Data** - the method identifier and ABI-encoded parameters, which can be obtained as follows: `web3.eth.abi.encodeFunctionSignature("totalSupply()")` which yields `0x18160ddd` -- **Block ID** - the block number, hash, or tag. Tag options include `latest,` `safe,` or `finalized` - -The prepared curl request is as follows: - -```bash title="eth_call JSON-RPC request" -curl https://ethereum.publicnode.com -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","data":"0x18160ddd"},"latest"],"id":1}' -``` - -And the corresponding response is: - -```bash title="eth_call JSON-RPC reponse" -{ - "jsonrpc":"2.0", - "id":1, - "result":"0x000000000000000000000000000000000000000000029fd3d129b582d7949e71" -} -``` - -Converting the returned value of the executed call from hexidecimal results in the value `3172615244782286193073777`. You can compare your result to the [**Read Contract**](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#readContract){target=\_blank} tab in Etherscan. Your result will be different as WETH is minted/burned over time. - ## Construct a Query {: #construct-a-query} You can use the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} to construct a query. You will also need an RPC endpoint from the provider of your choice. This example uses [Axios](https://www.npmjs.com/package/axios){target=\_blank} for RPC requests. Ensure that you also have [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed. @@ -310,24 +293,24 @@ This request consists of one `PerChainQueryRequest`, which is an `EthCallQueryRe ```jsx -// { -// "nonce": 0, -// "requests": [ -// { -// "chainId": 2, -// "query": { -// "callData": [ -// { -// "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", -// "data": "0x18160ddd" -// } -// ], -// "blockTag": "0x11e9068" -// } -// } -// ], -// "version": 1 -// } + // { + // "nonce": 0, + // "requests": [ + // { + // "chainId": 2, + // "query": { + // "callData": [ + // { + // "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + // "data": "0x18160ddd" + // } + // ], + // "blockTag": "0x11e9068" + // } + // } + // ], + // "version": 1 + // } ``` ## Mock a Query @@ -337,10 +320,10 @@ For easier testing, the Query SDK provides a `QueryProxyMock` method. This metho ```jsx const mockData = await mock.mock(request); console.log(mockData); -// { -// signatures: ['...'], -// bytes: '...' -// } + // { + // signatures: ['...'], + // bytes: '...' + // } ``` This response is suited for on-chain use, but the SDK also includes a parser to make the results readable via the client. @@ -352,7 +335,9 @@ const mockQueryResult = ( console.log( `Mock Query Result: ${mockQueryResult} (${BigInt(mockQueryResult)})` ); -// Mock Query Result: 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee (3172556167631284394053614) + // Mock Query Result: + // 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee + // (3172556167631284394053614) ``` Testing this all together might look like the following: @@ -435,7 +420,7 @@ anvil --fork-url https://ethereum.publicnode.com In order for mock requests to verify against the Mainnet Core Contract, you need to replace the current Guardian set with the single Devnet key used by the mock. -Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. +Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. ```jsx npx @wormhole-foundation/wormhole-cli evm hijack -a 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B -g 0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe @@ -449,14 +434,14 @@ The standardized means of making a `QueryRequest` with an API key is as follows: ```jsx const serialized = request.serialize(); -const proxyResponse = (await axios.post)( - QUERY_URL, +const proxyResponse = + (await axios.post) < + QueryProxyQueryResponse > + (QUERY_URL, { - bytes: Buffer.from(serialized).toString('hex'), + bytes: Buffer.from(serialized).toString("hex"), }, - { headers: { 'X-API-Key': YOUR_API_KEY } } -); - + { headers: { "X-API-Key": YOUR_API_KEY } }); ``` Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. @@ -642,2104 +627,2670 @@ const tx = await contract.updateCounters( ``` --- END CONTENT --- -## Basics Concepts [shared: true] +Doc-Content: https://wormhole.com/docs/products/queries/overview/ +--- BEGIN CONTENT --- +--- +title: Queries Overview +description: Learn how Wormhole Queries enable smart contracts to fetch real-time, Guardian-verified data across multiple blockchains. +categories: Queries +--- -The following section contains foundational documentation shared across all Wormhole products. -It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. -This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. -This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. +# Queries Overview ---- +Queries provide on-demand access to Guardian-attested on-chain data. They allow smart contracts to fetch real-time, verifiable data from across the multichain ecosystem, such as prices, rates, and liquidity. -## List of shared concept pages: +## Key Features +- **On-demand data access**: Fetch price feeds, interest rates, and other data in real-time. +- **Guardian attested**: All data is signed by [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} for trustless validation. +- **Cross-chain ready**: Request data on one chain, use it on another. +- **Smart contract integration**: Results are delivered as [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank}, readable by smart contracts. +- **Chain agnostic**: works across supported EVM chains, Solana, Sui, and [more](/docs/products/queries/reference/supported-networks/){target=\_blank}. -## Full content for shared concepts: +## How It Works -Doc-Content: https://wormhole.com/docs/learn/glossary/ ---- BEGIN CONTENT --- ---- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics ---- +A query request follows a simple but robust lifecycle. The off-chain service responsible for handling requests is called the CCQ Server (Cross-Chain Query Server), also referred to as the Query Server throughout this documentation. -# Glossary +1. An off-chain app sends a query to the CCQ Server via HTTPS +2. The CCQ Server checks the request and shares it with [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} +3. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} independently fetch the data, verify it, and sign the result +4. Once enough Guardians (2/3 quorum) return matching results, the CCQ Server aggregates and sends the final response +5. The off-chain app submits this result to a smart contract, which verifies the Guardian signatures and uses the data -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +The CCQ Server is permissioned but trustless. Most queries resolve in under one second, and Guardians retry failed requests for up to one minute. Up to 255 queries can be batched together to optimize performance, supporting efficient multichain workflows. -## Chain ID +![The architecture flow of a query](/docs/images/products/queries/overview/overview-1.webp) -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +## Use Cases -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +Queries enable a wide range of cross-chain applications. Below are common use cases and the Wormhole stack components you can use to build them. -## Consistency Level +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch rates and prices in real-time. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Sync actions between chains. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. -## Delivery Provider +- **Cross-Chain Swaps and Liquidity Aggregation (e.g., [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank})** -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch live prices optimal trade execution. + - [**Connect**](/docs/products/connect/overview/){target=\_blank}: Handle user-friendly asset transfers. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Moves native tokens. -## Emitter +- **Real-Time Price Feeds and Trading Strategies (e.g., [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank})** -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch price feeds. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Trigger trades. -## Finality +- **Multichain Prediction Markets** -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch market data and odds. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Automates token execution. -## Guardian +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Source data from chains. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Ensures tamper-proof data relay across networks. -## Guardian Network +## Next Steps -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +Follow these steps to get started with Queries: -## Guardian Set +[timeline(wormhole-docs/.snippets/text/products/queries/queries-timeline.json)] +--- END CONTENT --- -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +Doc-Content: https://wormhole.com/docs/products/queries/reference/supported-methods/ +--- BEGIN CONTENT --- +--- +title: Queries Supported Methods +description: Retrieve multichain data via historical timestamp queries, finality confirmation queries, and Solana lookups. +categories: Queries +--- -## Heartbeat +# Supported Methods -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. +Wormhole Queries provides on-demand access to [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}-attested on-chain data through a simple REST endpoint. It offers a faster, gasless alternative to traditional transaction-based data retrieval, removing the need for gas fees and transaction finality delays. Requests are handled off-chain and processed by the Guardians, delivering verified data efficiently and cost-effectively. -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +This page describes Wormhole Queries, their functionality, and available methods, aiming to assist new developers in utilizing the service. -## Observation +## Supported Query Types -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. +Wormhole currently supports five distinct query types, each designed for specific data retrieval tasks across various chains. -## Relayer +!!! note + For a more comprehensive technical description and further specifics on each query type, please consult the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md). -A relayer is any process that delivers VAAs to a destination. -## Sequence +### eth_call -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +The [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} query type allows you to perform read-only calls to a smart contract on a specific block, identified by its number or hash. Some of eth_call's configurations include: -## Spy +- **Batching** - group multiple calls, even to different contracts, into a single query targeting the same block, which is processed as one batch RPC call to simplify on-chain verification +- **Capacity** - batch up to 255 individual in a single eth_call query +- **Result data** - provides the specified block's number, hash, timestamp, and the output from the contract call -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. +### eth_call_by_timestamp -## VAA +The [`eth_call_by_timestamp`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#timestamp-and-block-id-hints-in-eth_call_by_timestamp){target=\_blank} query is similar to a standard `eth_call` but targets a specific timestamp instead of a block ID. This is useful for retrieving on-chain data based on a precise point in time, especially for correlating information across different chains. -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +The query returns your target timestamp and the latest block details at or before your specified `target_time` immediately preceding the subsequent block. -## Validator +### eth_call_with_finality -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +The [`eth_call_with_finality`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#desired-finality-in-eth_call_with_finality){target=\_blank} query type functions like a standard `eth_call`, but with an added critical assurance: it will only return the query results once the specified block has reached a designated level of finality on its chain. + +You can specify one of two finality levels for your query: + +- **Finalized** - indicates the highest level of assurance that a block is permanent and will not be altered or removed from the chain +- **Safe** - refers to a block considered highly unlikely to be reorganized, offering a substantial degree of confidence, though the network's consensus may not fully finalize it + +!!! note + If the target blockchain does not natively support or recognize the safe finality tag, requesting safe finality will be treated as a request for finalized finality instead. + +### sol_account + +The [`sol_account`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana-queries){target=\_blank} query reads on-chain data for one or more specified accounts on the Solana blockchain. This functionality is similar to using Solana's native [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} RPC method, enabling you to retrieve information for multiple accounts simultaneously + +### sol_pda + +The [`sol_pda`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana_queries){target=\_blank} query reads data for one or more Solana [Program Derived Addresses](https://www.anchor-lang.com/docs/pdas){target=\_blank}. It streamlines the standard process of deriving a PDA and fetching its account data. + +This is particularly useful for accessing multiple PDAs owned by a specific program or for verifying Solana PDA derivations on another blockchain, such as how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/queries/reference/supported-networks/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics +title: Queries Supported Networks +description: Reference table of chains supported by Wormhole Queries, including method support, finality, and expected historical data availability. +categories: Queries --- -# Infrastructure Components +# Supported Networks -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +This page provides a quick reference for chains supported by Wormhole Queries, including each chain's Wormhole chain ID and the level of support for key methods: [`eth_call`](/docs/products/queries/reference/supported-methods/#eth_call){target=\_blank}, [`eth_call_by_timestamp`](/docs/products/queries/reference/supported-methods/#eth_call_by_timestamp){target=\_blank}, and [`eth_call_with_finality`](/docs/products/queries/reference/supported-methods/#eth_call_with_finality){target=\_blank}. -## Get Started +The **Expected History** column shows how much recent state data is typically available for querying, though this can vary depending on the chain and the configuration of each Guardian node. -Start here for an overview of Wormhole architecture components and security mechanisms: +The support shown in the table reflects what has been confirmed through testing. However, query success ultimately depends on whether the underlying call can be executed on each Guardian’s RPC node. -
+For example, many chains use a fork of [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which by default retains 128 blocks of state in memory (unless archive mode is enabled). On Ethereum mainnet, this covers around 25 minutes of history—but on faster chains like Optimism, it may span only about three minutes. While Guardian nodes are expected to have access to recent state, there are currently no guarantees on how far back historical data is available. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Mainnet - --- +| Chain | Wormhole Chain ID | eth_call | eth_call_by_timestamp | eth_call_with_finality | Expected History | +|:-------------:|:-----------------:|:--------:|:---------------------:|:----------------------:|:----------------:| +| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | +| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | +| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | +| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | +| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | +| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | +| Karura | 11 | ✅ | ✅ | ✅ | archive | +| Acala | 12 | ✅ | ✅ | ✅ | archive | +| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | +| Celo | 14 | ✅ | ℹ️ | ✅ | 128 blocks | +| Moonbeam | 16 | ✅ | ℹ️ | ✅ | 256 blocks | +| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | +| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | +| Base | 30 | ✅ | ✅ | ✅ | archive | - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +ℹ️`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. +--- END CONTENT --- - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +## Basics Concepts [shared: true] -- :octicons-book-16:{ .lg .middle } **Security** +The following section contains foundational documentation shared across all Wormhole products. +It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. +This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. +This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. - --- +--- - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +## List of shared concept pages: - [:custom-arrow: Learn About Security](/docs/learn/security/) -
+## Full content for shared concepts: -## Explore Components +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK +--- -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +# Get Started with Messaging -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. +## Prerequisites -## Next Steps +Before you begin, ensure you have the following: -
+- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -- :octicons-book-16:{ .lg .middle } **Messaging Components** +## Configure Your Messaging Environment - --- +1. Create a directory and initialize a Node.js project: - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + ```bash + mkdir core-message + cd core-message + npm init -y + ``` - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` - --- +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. + ```bash + npx tsc --init + ``` - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -
---- END CONTENT --- +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + ```bash + npm install @wormhole-foundation/sdk + ``` -# Architecture +5. Create a new file named `main.ts`: -## Overview + ```bash + touch main.ts + ``` -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); -## On-Chain Components + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -## Off-Chain Components + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -## Next Steps + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -
+ // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -- :octicons-book-16:{ .lg .middle } **Core Contracts** +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` - --- + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. +2. Run the script using the following command: - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + ```bash + npx tsx main.ts + ``` -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
- --- +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +## Next Steps -
+- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Core Contracts +# Get Started with Core Contracts ## Introduction -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -## Key Functions +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -Key functions of the Wormhole Core Contract include the following: +## Prerequisites -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +To interact with the Wormhole Core Contract, you'll need the following: -## How the Core Contract Works +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. +## How to Interact with Core Contracts -The following describes the role of the Wormhole Core Contract in message transfers: +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -### Message Submission +### Sending Messages -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page +=== "EVM" -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -### Message Reception + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + ??? interface "Parameters" -## Multicast + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + --- -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + --- -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -## Next Steps + ??? interface "Returns" -
+ `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); - --- +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. +// Check fee and send parameters - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); - --- +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) +=== "Solana" -
---- END CONTENT --- + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -## Guardian + ??? interface "Parameters" -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -Guardians fulfill their role in the messaging protocol as follows: + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -## Guardian Network + ??? child "Type `PostMessage<'info>`" -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -The Guardian Network is designed to help Wormhole deliver on five key principles: + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing + --- -The following sections explore each principle in detail. + `batch_id` ++"u32"++ + + An identifier for the message batch. -### Decentralization + --- -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -Two common approaches to decentralization have notable limitations: + --- -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -To answer that, consider these key constraints and design decisions: + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -### Modularity + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -### Chain Agnosticism +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +### Receiving Messages -### Scalability +The way a message is received and handled depends on the environment. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +=== "EVM" -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -### Upgradeable + ??? interface "Parameters" -Wormhole is designed to adapt and evolve in the following ways: + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + ??? interface "Returns" -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -## Next Steps + ??? child "Struct `VM`" -
+ ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -- :octicons-book-16:{ .lg .middle } **Relayers** + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. - --- + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) + ??? interface "Example" -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); - --- + // Perform safety checks here - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + // Your custom application logic here +} + ``` -
---- END CONTENT --- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +=== "Solana" -# Relayers + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. + Retrieve the raw message data: -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -There are three primary types of relayers discussed: + ??? interface "Example" -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -## Fundamentals +#### Validating the Emitter -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -Key characteristics of VAAs include: +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -- Public emission from the Guardian Network +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- Authentication through signatures from the Guardian Network +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -- Verifiability by any entity or any Wormhole Core Contract +await tx.wait(); +``` -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +#### Additional Checks -Keep in mind the following security considerations around relayers: +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +## Source Code References -## Client-Side Relaying +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -### Key Features +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +# Wormhole Relayer -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +## Introduction -### Implementation +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -Users themselves carry out the three steps of the cross-chain process: +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -1. Perform an action on chain A +## Get Started with the Wormhole Relayer -2. Retrieve the resulting VAA from the Guardian Network +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -3. Perform an action on chain B using the VAA +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -### Considerations +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +### Wormhole Relayer Interfaces -- Users must sign all required transactions with their own wallet +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -- Users must have funds to pay the transaction fees on every chain involved +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- The user experience may be cumbersome due to the manual steps involved +## Interact with the Wormhole Relayer -## Custom Relayers +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -### Key Features +Your initial set up should resemble the following: -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +contract Example { + IWormholeRelayer public wormholeRelayer; -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -### Implementation +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +### Send a Message -### Considerations +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -- Development work and hosting of relayers are required +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -## Wormhole Relayers +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -### Key Features +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +### Receive a Message -### Implementation +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -The Wormhole relayer integration involves two key steps: +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +## Delivery Guarantees -### Considerations +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- All computations are performed on-chain +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -- Potentially less gas-efficient compared to custom relayers +## Delivery Statuses -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- Support may not be available for all chains +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -## Next Steps +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -
+- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -- :octicons-book-16:{ .lg .middle } **Spy** +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. - --- +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +## Other Considerations - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent - --- +## Track the Progress of Messages with the Wormhole CLI - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: + +=== "Mainnet" - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +=== "Testnet" - --- + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Step-by-Step Tutorial -
+For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. categories: Basics --- -# Spy +# Messaging Overview -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Key Features -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -## Key Features +## How It Works -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +The messaging flow consists of several core components: -## Integrator Use Case +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +## Use Cases -## Observable Message Categories +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -A Spy can access the following categories of messages shared over the gossip protocol: +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +- **Gas Abstraction** -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +- **Bridging Intent Library** -## Additional Resources + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -
+- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- :octicons-code-16:{ .lg .middle } **Spy Source Code** + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. - --- +## Next Steps - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +Follow these steps to work with Wormhole Messaging: - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- - --- +# Products - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. - --- +## Transfer Products - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-## Next Steps +::spantable:: -
+| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | -- :octicons-code-16:{ .lg .middle } **Run a Spy** +::end-spantable:: - --- +
- Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +
-- :octicons-code-16:{ .lg .middle } **Use Queries** +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - --- +## Bridging UI - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +## Real-time Data -
+[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + +## Multichain Governance + +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. +# Glossary -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +## Chain ID -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -## VAA Format +## Consistency Level -The basic VAA consists of header and body components described as follows: +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +## Delivery Provider - Where each `signature` is: +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +## Emitter -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +## Finality -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +## Guardian -## Consistency and Finality +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +## Guardian Network -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -## Signatures +## Guardian Set -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` +## Heartbeat -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. -## Payload Types +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +## Observation -### Token Transfer +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +## Relayer -Transferring tokens from the sending chain to the destination chain requires the following steps: +A relayer is any process that delivers VAAs to a destination. -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +## Sequence -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +## Spy -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## VAA -### Attestation +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +## Validator -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- -The message format for token attestation is as follows: +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +# Architecture -#### Attestation Tips +## Overview -Be aware of the following considerations when working with attestations: +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer - -### Token Transfer with Message - -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +## On-Chain Components -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## Off-Chain Components -### Governance +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +## Next Steps -#### Action Structure +
-Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +- :octicons-book-16:{ .lg .middle } **Core Contracts** -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action + --- -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -#### Actions +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: + --- -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -## Lifetime of a Message + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +
+--- END CONTENT --- -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +# The Wormhole Ecosystem -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -## Next Steps +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-book-16:{ .lg .middle } **Guardians** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. categories: Basics --- -# Introduction to Wormhole +# Core Contracts -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +## Introduction -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +## Key Functions -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +Key functions of the Wormhole Core Contract include the following: -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## How the Core Contract Works -## What Problems Does Wormhole Solve? +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following describes the role of the Wormhole Core Contract in message transfers: -Critical problems Wormhole addresses include: +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -## What Does Wormhole Offer? +### Message Submission -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -## What Isn't Wormhole? +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +### Message Reception -## Use Cases of Wormhole +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -Consider the following examples of potential applications enabled by Wormhole: +## Multicast -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -## Explore +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -Discover more about the Wormhole ecosystem, components, and protocols: +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -## Demos +## Next Steps -Demos offer more realistic implementations than tutorials: +
-- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** - + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -!!! note - Wormhole Integration Complete? + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** + --- -## Supported Blockchains + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -Wormhole supports a growing number of blockchains. + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Security +## Guardian -## Core Security Assumptions +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Guardians fulfill their role in the messaging protocol as follows: -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -In summary: +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +## Guardian Network -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## Guardian Network +The Guardian Network is designed to help Wormhole deliver on five key principles: -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Governance +The following sections explore each principle in detail. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +### Decentralization -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +Two common approaches to decentralization have notable limitations: -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -Via governance, the Guardians can: +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +To answer that, consider these key constraints and design decisions: -## Monitoring +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +### Modularity -Guardians monitor: +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Chain Agnosticism -## Asset Layer Protections +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +### Scalability -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -## Open Source +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -Wormhole builds in the open and is always open source. +### Upgradeable -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +Wormhole is designed to adapt and evolve in the following ways: -## Audits +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +## Next Steps -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +
-## Bug Bounties +- :octicons-book-16:{ .lg .middle } **Relayers** -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + --- -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -## Learn More + --- -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Get Started with Core Contracts +# Relayers -## Introduction +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +There are three primary types of relayers discussed: -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -## Prerequisites +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -To interact with the Wormhole Core Contract, you'll need the following: +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +## Fundamentals -## How to Interact with Core Contracts +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +Key characteristics of VAAs include: -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- Public emission from the Guardian Network -### Sending Messages +- Authentication through signatures from the Guardian Network -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +- Verifiability by any entity or any Wormhole Core Contract -=== "EVM" +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +Keep in mind the following security considerations around relayers: - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks - ??? interface "Parameters" +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain - --- +## Client-Side Relaying - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. - --- +### Key Features - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs - ??? interface "Returns" +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +### Implementation - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +Users themselves carry out the three steps of the cross-chain process: -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +1. Perform an action on chain A -// Check fee and send parameters +2. Retrieve the resulting VAA from the Guardian Network -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +3. Perform an action on chain B using the VAA -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +### Considerations -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- Users must sign all required transactions with their own wallet -=== "Solana" +- Users must have funds to pay the transaction fees on every chain involved - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- The user experience may be cumbersome due to the manual steps involved - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +## Custom Relayers - ??? interface "Parameters" +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +### Key Features - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - ??? child "Type `PostMessage<'info>`" +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +### Implementation - --- +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - `batch_id` ++"u32"++ - - An identifier for the message batch. +### Considerations - --- +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +- Development work and hosting of relayers are required - --- +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +## Wormhole Relayers - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +### Key Features -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +### Implementation -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +The Wormhole relayer integration involves two key steps: -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract -### Receiving Messages +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -The way a message is received and handled depends on the environment. +### Considerations -=== "EVM" +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +- All computations are performed on-chain - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- Potentially less gas-efficient compared to custom relayers - ??? interface "Parameters" +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. +- Support may not be available for all chains - ??? interface "Returns" +## Next Steps - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +
- ??? child "Struct `VM`" +- :octicons-book-16:{ .lg .middle } **Spy** - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + --- - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - ??? interface "Example" + --- - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - // Perform safety checks here + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - // Your custom application logic here -} - ``` + --- - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -=== "Solana" + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +
+--- END CONTENT --- - Retrieve the raw message data: +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +# Spy + +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. + +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. + +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. + +## Key Features + +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure + +## Integrator Use Case + +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ??? interface "Example" +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +## Observable Message Categories - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +A Spy can access the following categories of messages shared over the gossip protocol: - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data -#### Validating the Emitter + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +## Additional Resources -await tx.wait(); -``` +
-#### Additional Checks +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + --- -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -## Source Code References +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + --- -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -# Wormhole Relayer +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -## Introduction + --- -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -## Get Started with the Wormhole Relayer +
-Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +## Next Steps -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +
-
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+- :octicons-code-16:{ .lg .middle } **Run a Spy** -### Wormhole Relayer Interfaces + --- -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -## Interact with the Wormhole Relayer +- :octicons-code-16:{ .lg .middle } **Use Queries** -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + --- -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -Your initial set up should resemble the following: +
+--- END CONTENT --- -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +# Verified Action Approvals -contract Example { - IWormholeRelayer public wormholeRelayer; +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -### Send a Message +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +## VAA Format -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +The basic VAA consists of header and body components described as follows: -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` + Where each `signature` is: -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -### Receive a Message +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +## Consistency and Finality -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -## Delivery Guarantees +## Signatures -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -## Delivery Statuses +## Payload Types -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +### Token Transfer -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +Transferring tokens from the sending chain to the destination chain requires the following steps: -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: + +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -## Other Considerations +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +### Attestation -## Track the Progress of Messages with the Wormhole CLI +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -=== "Mainnet" +The message format for token attestation is as follows: - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -=== "Testnet" +#### Attestation Tips - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +Be aware of the following considerations when working with attestations: -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -## Step-by-Step Tutorial +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -# Products +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +### Token Transfer with Message -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -## Transfer Products +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +### Governance -
+Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -::spantable:: +#### Action Structure -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -::end-spantable:: +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -
+Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Bridging UI +#### Actions -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -## Real-time Data +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +## Lifetime of a Message -## Multichain Governance +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -# Wormhole Use Cases +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -
-
+## Next Steps -## Cross-Chain Swaps and Liquidity Aggregation +
-Enable seamless swaps between chains with real-time liquidity routing. +- :octicons-book-16:{ .lg .middle } **Guardians** -
-
+ --- -🛠 **Wormhole products used:** + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -
-
+ --- + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -
-
+ [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -## Borrowing and Lending Across Chains +
+--- END CONTENT --- -Let users borrow assets on one chain using collateral from another. +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -
-
+# Introduction to Wormhole -🛠 **Wormhole products used:** +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -
-
+![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -
-
+Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -## Real-Time Price Feeds and Trading Strategies +This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -Fetch price feeds across multiple chains for DeFi applications. +## What Problems Does Wormhole Solve? -
-
+Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -🛠 **Wormhole products used:** +Critical problems Wormhole addresses include: -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +## What Does Wormhole Offer? -
-
+Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -
-
+## What Isn't Wormhole? -## Asset Movement Between Bitcoin and Other Chains +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -Enable direct BTC transfers without wrapped assets. +## Use Cases of Wormhole -
-
+Consider the following examples of potential applications enabled by Wormhole: -🛠 **Wormhole products used:** +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +## Explore -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +Discover more about the Wormhole ecosystem, components, and protocols: -
-
+- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -## Decentralized Social Platforms +Demos offer more realistic implementations than tutorials: -Enable seamless communication and asset transfer across decentralized social networks. +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -
-
+ -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +!!! note + Wormhole Integration Complete? -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +## Supported Networks by Product -
-
+Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -## Memecoin Launchpads +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +# Security -
-
+## Core Security Assumptions -🛠 **Wormhole products used:** +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -
-
+## Guardian Network -## Cross-Chain Perpetuals +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +### Governance -
-
+Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -🛠 **Wormhole products used:** +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -
-
+The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -## Gas Abstraction +## Monitoring -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -
-
+Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -🛠 **Wormhole products used:** +Guardians monitor: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +## Asset Layer Protections -
-
+One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -
-
+In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -## Bridging Intent Library +## Open Source -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +Wormhole builds in the open and is always open source. -
-
+- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -🛠 **Wormhole products used:** +## Audits -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -
-
+All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +## Bug Bounties -
-
+Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -## Multichain Prediction Markets +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -
-
+For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -🛠 **Wormhole products used:** +## Learn More -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -
-
+## Install the SDK -## Cross-Chain Payment Widgets +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -
-
+## Key Components -🛠 **Wormhole products used:** +The following key components and features work together to make your on-chain Wormhole integration easier to build. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +??? interface "Base contracts" -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. +??? interface "Interfaces" -
-
+ Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -## Oracle Networks + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. +??? interface "Constants" -
-
+ Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -🛠 **Wormhole products used:** + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +## Example Usage -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -
-
+### Set Up a Project -## Cross-Chain Staking +Follow these steps to prepare your development environment: -Enable users to stake assets on one chain while earning rewards or securing networks on another. +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -
-
+ ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -🛠 **Wormhole products used:** +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -
-
---- END CONTENT --- + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -## Reference Concepts [shared: true] + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. ---- +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -## List of shared concept pages: +## Use Contracts to Transfer USDC +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -## Full content for shared concepts: + ```bash + touch script/transfer.ts + ``` -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -# Reference +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -## Get Started + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -
+ // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - --- + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } - --- + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -2862,7 +3413,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -2917,7 +3468,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -3133,262 +3684,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -3400,7 +3785,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -3575,7 +3960,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -3656,4 +4041,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-reference.txt b/llms-files/llms-reference.txt index ffbe247c6..a39d66c2d 100644 --- a/llms-files/llms-reference.txt +++ b/llms-files/llms-reference.txt @@ -6,78 +6,16 @@ It is intended for use with large language models (LLMs) to support developers w This file includes documentation related to the category: Reference ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/chain-ids.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/consistency-levels.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/contract-addresses.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/wormhole-formatted-addresses.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/supported-networks.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/testnet-faucets.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/chain-ids.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/consistency-levels.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/contract-addresses.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/supported-networks.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/testnet-faucets.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/wormhole-formatted-addresses.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- - -# Reference - -## Get Started - -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. - -
- -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** - - --- - - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. - - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) - -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** - - --- - - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. - - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) - -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** - - --- - - Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. - - This includes the following protocol contracts: - - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP - - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) - -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** - - --- - - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. - - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -200,7 +138,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -255,7 +193,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -532,23 +470,11 @@ categories: Reference === "Mainnet" - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
=== "Testnet" - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
## Read-Only Deployments @@ -572,161 +498,7 @@ categories: Reference Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: - -=== "EVM" - - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; - -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` - -=== "Solana" - - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; - -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` - -The result is a standardized address format that is ready for cross-chain operations. - -### Convert Back to Native Addresses - -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: - -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); - -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` - -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. - -## Use Cases for Wormhole Formatted Addresses - -### Cross-chain Token Transfers - -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. - -### Smart Contract Interactions - -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. - -### DApp Development - -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. - -### Relayers and Infrastructure - -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -738,7 +510,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -913,7 +685,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -994,4 +766,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-relayers.txt b/llms-files/llms-relayers.txt index cb1b7d8b2..43bcf31d3 100644 --- a/llms-files/llms-relayers.txt +++ b/llms-files/llms-relayers.txt @@ -13,13 +13,12 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/wormhole-relayers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers/run-relayer.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/wormhole-relayers.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure-guides/run-relayer.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ --- BEGIN CONTENT --- --- title: Wormhole-Deployed Relayers @@ -31,18 +30,18 @@ categories: Relayers, Basics ## Introduction -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. ## Get Started with the Wormhole Relayer -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying.
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) + ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp)
The components outlined in blue must be implemented.
@@ -60,7 +59,7 @@ To start interacting with the Wormhole relayer in your contracts, you'll need to To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. Your initial set up should resemble the following: @@ -203,7 +202,7 @@ Some implementation details should be considered during development to ensure sa ## Track the Progress of Messages with the Wormhole CLI -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: === "Mainnet" @@ -217,78 +216,14 @@ While no off-chain programs are required, a developer may want to track the prog worm status testnet ethereum INSERT_TRANSACTION_HASH ``` -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. ## Step-by-Step Tutorial -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/infrastructure/relayers/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. -categories: Relayers ---- - -# Relayers - -## Get Started - -
- -- :octicons-terminal-16:{ .lg .middle } **Run a Custom Relayer** - - --- - - This section guides you through developing your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. - -
- - Benefits of running your own relayer: - - - You can add logic to customize the delivery of messages - - You can perform off-chain computations resulting in optimized gas costs - -
- - Requirements for running your own relayer: - - - You are responsible for developing and hosting your relayer - - You are responsible for paying target chain fees - - You are responsible for the liveness of your relayer - -
- - [:custom-arrow: Get started now](/docs/infrastructure/relayers/run-relayer/) - -
- -## Additional Resources - -
- -- :octicons-question-16:{ .lg .middle } **What is a Relayer?** - - --- - - Learn about what a relayer is, what role it plays in the delivery of cross-chain messages, and the different types of relayers in the Wormhole ecosystem. - - [:custom-arrow: Learn more about relayers](/docs/learn/infrastructure/relayer/) - -- :octicons-gear-16:{ .lg .middle } **Simplify the Development Process** - - --- - - Use the Wormhole Relayer Engine package as a foundational toolkit to develop your own customized off-chain relaying service, enabling tailored message handling. - - [:custom-arrow: Check out the Relayer Engine source code](https://github.com/wormhole-foundation/relayer-engine){target=\_blank} - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/infrastructure/relayers/run-relayer/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure-guides/run-relayer/ --- BEGIN CONTENT --- --- title: Run a Relayer @@ -313,7 +248,7 @@ This guide teaches you how to set up and configure a custom relayer for efficien To start building a custom relayer, it's essential to grasp the components you'll be managing as part of your relaying service. Your relayer must be capable of retrieving and delivering VAAs.
- ![Custom relayer](/docs/images/build/infrastructure/relayers/run-relayer/relayer-1.webp) + ![Custom relayer](/docs/images/protocol/infrastructure-guides/run-relayer/relayer-1.webp)
The off-chain components outlined in blue must be implemented.
@@ -454,7 +389,7 @@ The source code for this example is available in the [`relayer-engine` repositor Next, you must start a Spy to listen for available VAAs published on the Guardian network. You also need a persistence layer. This example uses Redis. -More details about the Spy are available in the [Spy Documentation](/docs/learn/infrastructure/spy){target=\_blank}. +More details about the Spy are available in the [Spy Documentation](/docs/protocol/infrastructure/spy){target=\_blank}. ### Wormhole Network Spy @@ -630,2090 +565,2485 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary +# Get Started with Messaging -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Chain ID +## Prerequisites -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +Before you begin, ensure you have the following: -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -## Consistency Level +## Configure Your Messaging Environment -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a directory and initialize a Node.js project: -## Delivery Provider + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Emitter + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Finality + ```bash + npx tsc --init + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + Make sure your `tsconfig.json` includes the following settings: -## Guardian + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Guardian Network + ```bash + npm install @wormhole-foundation/sdk + ``` -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. Create a new file named `main.ts`: -## Guardian Set + ```bash + touch main.ts + ``` -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Heartbeat + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -## Observation + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -## Relayer + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -A relayer is any process that delivers VAAs to a destination. + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -## Sequence +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -## Spy +2. Run the script using the following command: -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + ```bash + npx tsx main.ts + ``` -## VAA + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -## Validator +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +## Next Steps + +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Infrastructure Components +# Get Started with Core Contracts -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +## Introduction -## Get Started +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -Start here for an overview of Wormhole architecture components and security mechanisms: +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -
+This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Prerequisites - --- +To interact with the Wormhole Core Contract, you'll need the following: - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +## How to Interact with Core Contracts -- :octicons-book-16:{ .lg .middle } **Security** +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - --- +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. - [:custom-arrow: Learn About Security](/docs/learn/security/) +### Sending Messages -
+To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -## Explore Components +=== "EVM" -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. + ??? interface "Parameters" -## Next Steps + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -
+ --- -- :octicons-book-16:{ .lg .middle } **Messaging Components** + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - --- + --- - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + ??? interface "Returns" -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" - --- + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +// Check fee and send parameters -
---- END CONTENT --- +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -# Architecture +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -## Overview + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +=== "Solana" -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + ??? interface "Parameters" - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -## On-Chain Components + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -## Off-Chain Components + ??? child "Type `PostMessage<'info>`" -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -## Next Steps + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -
+ --- -- :octicons-book-16:{ .lg .middle } **Core Contracts** + `batch_id` ++"u32"++ + + An identifier for the message batch. - --- + --- - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" - --- + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -
---- END CONTENT --- +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -# Core Contracts + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -## Introduction +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. +### Receiving Messages -## Key Functions +The way a message is received and handled depends on the environment. -Key functions of the Wormhole Core Contract include the following: +=== "EVM" -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -## How the Core Contract Works + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. + ??? interface "Parameters" -The following describes the role of the Wormhole Core Contract in message transfers: + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions + ??? interface "Returns" -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -### Message Submission + ??? child "Struct `VM`" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -### Message Reception + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + ??? interface "Example" -## Multicast + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + // Perform safety checks here -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + // Your custom application logic here +} + ``` -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -## Next Steps +=== "Solana" -
+ On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + Retrieve the raw message data: - --- + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + ??? interface "Example" - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` - --- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. +#### Validating the Emitter - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -
---- END CONTENT --- +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -## Guardian +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -Guardians fulfill their role in the messaging protocol as follows: +await tx.wait(); +``` -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +#### Additional Checks -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -## Guardian Network +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -The Guardian Network is designed to help Wormhole deliver on five key principles: +## Source Code References -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -The following sections explore each principle in detail. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -### Decentralization +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +# Wormhole Relayer -Two common approaches to decentralization have notable limitations: +## Introduction -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +## Get Started with the Wormhole Relayer -To answer that, consider these key constraints and design decisions: +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-### Modularity +### Wormhole Relayer Interfaces -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -### Chain Agnosticism +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +## Interact with the Wormhole Relayer -### Scalability +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +Your initial set up should resemble the following: -### Upgradeable +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -Wormhole is designed to adapt and evolve in the following ways: +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +contract Example { + IWormholeRelayer public wormholeRelayer; -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -## Next Steps +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -
+### Send a Message -- :octicons-book-16:{ .lg .middle } **Relayers** +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. - --- +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` - --- +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -
---- END CONTENT --- +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +### Receive a Message -# Relayers +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -There are three primary types of relayers discussed: +## Delivery Guarantees -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -## Fundamentals +## Delivery Statuses -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -Key characteristics of VAAs include: +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- Public emission from the Guardian Network +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -- Authentication through signatures from the Guardian Network +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -- Verifiability by any entity or any Wormhole Core Contract +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +## Other Considerations -Keep in mind the following security considerations around relayers: +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +## Track the Progress of Messages with the Wormhole CLI -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -## Client-Side Relaying +=== "Mainnet" -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -### Key Features +=== "Testnet" -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -### Implementation +## Step-by-Step Tutorial -Users themselves carry out the three steps of the cross-chain process: +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -1. Perform an action on chain A +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -2. Retrieve the resulting VAA from the Guardian Network +# Messaging Overview -3. Perform an action on chain B using the VAA +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -### Considerations +## Key Features -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- Users must sign all required transactions with their own wallet +## How It Works -- Users must have funds to pay the transaction fees on every chain involved +The messaging flow consists of several core components: -- The user experience may be cumbersome due to the manual steps involved +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -## Custom Relayers +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +## Use Cases -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Key Features +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +- **Gas Abstraction** -### Implementation + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +- **Bridging Intent Library** -### Considerations + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- Development work and hosting of relayers are required + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +## Next Steps -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +Follow these steps to work with Wormhole Messaging: -## Wormhole Relayers +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Key Features +# Products -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -### Implementation +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -The Wormhole relayer integration involves two key steps: +## Transfer Products -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -### Considerations +
-Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +::spantable:: -- All computations are performed on-chain +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | -- Potentially less gas-efficient compared to custom relayers +::end-spantable:: -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +
-- Support may not be available for all chains +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: -## Next Steps +
-
+Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. -- :octicons-book-16:{ .lg .middle } **Spy** +## Bridging UI - --- +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +## Real-time Data - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +## Multichain Governance - --- +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ +--- BEGIN CONTENT --- +--- +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +categories: Basics +--- - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +# Glossary -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - --- +## Chain ID - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -
---- END CONTENT --- +## Consistency Level -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ ---- BEGIN CONTENT --- ---- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -categories: Basics ---- +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -# Spy +## Delivery Provider -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Emitter -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -## Key Features +## Finality -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -## Integrator Use Case +## Guardian -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +## Guardian Network -## Observable Message Categories +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -A Spy can access the following categories of messages shared over the gossip protocol: +## Guardian Set -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +## Heartbeat -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +## Observation - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -## Additional Resources +## Relayer -
+A relayer is any process that delivers VAAs to a destination. -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +## Sequence - --- +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +## Spy - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +## VAA - --- +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +## Validator - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- - --- +# Architecture - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +## Overview + +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -
+The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + +## On-Chain Components + +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + +## Off-Chain Components + +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers ## Next Steps
-- :octicons-code-16:{ .lg .middle } **Run a Spy** +- :octicons-book-16:{ .lg .middle } **Core Contracts** --- - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -- :octicons-code-16:{ .lg .middle } **Use Queries** +- :octicons-tools-16:{ .lg .middle } **Core Messaging** --- - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. categories: Basics --- -# Verified Action Approvals +# The Wormhole Ecosystem -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Ecosystem Overview -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -## VAA Format +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -The basic VAA consists of header and body components described as follows: +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +## Bringing It All Together: Interoperability in Action - Where each `signature` is: +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## Next Steps -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +# Core Contracts -## Consistency and Finality +## Introduction -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -## Signatures +## Key Functions -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +Key functions of the Wormhole Core Contract include the following: -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +## How the Core Contract Works -## Payload Types +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +The following describes the role of the Wormhole Core Contract in message transfers: -### Token Transfer +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -Transferring tokens from the sending chain to the destination chain requires the following steps: +### Message Submission -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +### Message Reception -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -### Attestation +## Multicast -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -The message format for token attestation is as follows: +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -#### Attestation Tips +## Next Steps -Be aware of the following considerations when working with attestations: +
-- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes + --- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** -### Token Transfer with Message + --- -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +
+--- END CONTENT --- -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ +--- BEGIN CONTENT --- +--- +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +categories: Basics +--- -### Governance +## Guardian -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -#### Action Structure +Guardians fulfill their role in the messaging protocol as follows: -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +## Guardian Network -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -#### Actions +The Guardian Network is designed to help Wormhole deliver on five key principles: -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +The following sections explore each principle in detail. -## Lifetime of a Message +### Decentralization -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Two common approaches to decentralization have notable limitations: -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment + +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. + +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? + +To answer that, consider these key constraints and design decisions: + +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants + +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. + +### Modularity + +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. + +### Chain Agnosticism + +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. + +### Scalability -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. + +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. + +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. + +### Upgradeable + +Wormhole is designed to adapt and evolve in the following ways: + +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Relayers** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Queries](/docs/products/queries/overview/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Introduction to Wormhole +# Relayers -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +There are three primary types of relayers discussed: -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## Fundamentals -## What Problems Does Wormhole Solve? +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -Critical problems Wormhole addresses include: +Key characteristics of VAAs include: -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +- Public emission from the Guardian Network -## What Does Wormhole Offer? +- Authentication through signatures from the Guardian Network -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +- Verifiability by any entity or any Wormhole Core Contract -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -## What Isn't Wormhole? +Keep in mind the following security considerations around relayers: -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## Use Cases of Wormhole +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -Consider the following examples of potential applications enabled by Wormhole: +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +## Client-Side Relaying -## Explore +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -Discover more about the Wormhole ecosystem, components, and protocols: +### Key Features -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -## Demos +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -Demos offer more realistic implementations than tutorials: +### Implementation -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +Users themselves carry out the three steps of the cross-chain process: - +2. Retrieve the resulting VAA from the Guardian Network -!!! note - Wormhole Integration Complete? +3. Perform an action on chain B using the VAA - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +### Considerations - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -## Supported Blockchains +- Users must sign all required transactions with their own wallet -Wormhole supports a growing number of blockchains. +- Users must have funds to pay the transaction fees on every chain involved -text/supported-networks.md ---- END CONTENT --- +- The user experience may be cumbersome due to the manual steps involved -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- +## Custom Relayers -# Security +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -## Core Security Assumptions +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +### Key Features -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -In summary: +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience -## Guardian Network +### Implementation -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. -### Governance +### Considerations -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +- Development work and hosting of relayers are required -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- Relayers are responsible for availability, and adding dependencies for the cross-chain application -Via governance, the Guardians can: +## Wormhole Relayers -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +### Key Features -## Monitoring +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +### Implementation -Guardians monitor: +The Wormhole relayer integration involves two key steps: -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract -## Asset Layer Protections +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +### Considerations -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +- All computations are performed on-chain -## Open Source +- Potentially less gas-efficient compared to custom relayers -Wormhole builds in the open and is always open source. +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +- Support may not be available for all chains -## Audits +## Next Steps -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +
-- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +- :octicons-book-16:{ .lg .middle } **Spy** -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. + --- -## Bug Bounties + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + --- -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -## Learn More + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** + + --- + + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. + + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. categories: Basics --- -# Get Started with Core Contracts - -## Introduction - -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. - -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. - -## Prerequisites - -To interact with the Wormhole Core Contract, you'll need the following: - -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - -## How to Interact with Core Contracts - -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network - -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. - -### Sending Messages - -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. - -=== "EVM" - - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: - - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` - - ??? interface "Parameters" - - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. - - --- - - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - - --- - - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - - ??? interface "Returns" - - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" - - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); - -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); - -// Check fee and send parameters - -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); - -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); - -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - -=== "Solana" - - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: - - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` - - ??? interface "Parameters" - - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" - - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. - - ??? child "Type `PostMessage<'info>`" - - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` - - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - - --- - - `batch_id` ++"u32"++ - - An identifier for the message batch. - - --- - - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. - - --- - - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" - - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" - - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" - - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters - -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; - -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. - -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. - -### Receiving Messages - -The way a message is received and handled depends on the environment. - -=== "EVM" - - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. - - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` - - ??? interface "Parameters" - - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. - - ??? interface "Returns" - - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. - - ??? child "Struct `VM`" - - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` - - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. - - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- - - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided - - ??? interface "Example" - - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +# Spy - // Perform safety checks here +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - // Your custom application logic here -} - ``` +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +## Key Features -=== "Solana" +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +## Integrator Use Case - Retrieve the raw message data: +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ??? interface "Example" +## Observable Message Categories - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +A Spy can access the following categories of messages shared over the gossip protocol: - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -#### Validating the Emitter +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +## Additional Resources -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +
-await tx.wait(); -``` +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -#### Additional Checks + --- -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -## Source Code References + --- -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -# Wormhole Relayer + --- -## Introduction + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +
-## Get Started with the Wormhole Relayer +## Next Steps -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +
-To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +- :octicons-code-16:{ .lg .middle } **Run a Spy** -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+ --- -### Wormhole Relayer Interfaces + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from +- :octicons-code-16:{ .lg .middle } **Use Queries** -## Interact with the Wormhole Relayer + --- -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +
+--- END CONTENT --- -Your initial set up should resemble the following: +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +# Verified Action Approvals -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -contract Example { - IWormholeRelayer public wormholeRelayer; +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -### Send a Message +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +## VAA Format -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +The basic VAA consists of header and body components described as follows: -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. + Where each `signature` is: -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -### Receive a Message +## Consistency and Finality -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +## Signatures -## Delivery Guarantees +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +## Payload Types -## Delivery Statuses +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +### Token Transfer -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +Transferring tokens from the sending chain to the destination chain requires the following steps: -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer + +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -## Other Considerations +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +### Attestation -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -## Track the Progress of Messages with the Wormhole CLI +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +The message format for token attestation is as follows: -=== "Mainnet" +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +#### Attestation Tips -=== "Testnet" +Be aware of the following considerations when working with attestations: - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -## Step-by-Step Tutorial +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -# Products +### Token Transfer with Message -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -## Transfer Products +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +### Governance -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -
+#### Action Structure -::spantable:: +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -::end-spantable:: +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -
+```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +#### Actions -## Bridging UI +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -## Real-time Data +## Lifetime of a Message -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -## Multichain Governance +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -# Wormhole Use Cases +## Next Steps -
-
+
-## Cross-Chain Swaps and Liquidity Aggregation +- :octicons-book-16:{ .lg .middle } **Guardians** -Enable seamless swaps between chains with real-time liquidity routing. + --- -
-
+ Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -🛠 **Wormhole products used:** + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + --- -
-
+ Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -
-
+
+--- END CONTENT --- -## Borrowing and Lending Across Chains +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -Let users borrow assets on one chain using collateral from another. +# Introduction to Wormhole -
-
+In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -🛠 **Wormhole products used:** +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -
-
+!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
-
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -## Real-Time Price Feeds and Trading Strategies +## What Problems Does Wormhole Solve? -Fetch price feeds across multiple chains for DeFi applications. +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -
-
+Critical problems Wormhole addresses include: -🛠 **Wormhole products used:** +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +## What Does Wormhole Offer? -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -
-
+- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. +## What Isn't Wormhole? -
-
+- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -## Asset Movement Between Bitcoin and Other Chains +## Use Cases of Wormhole -Enable direct BTC transfers without wrapped assets. +Consider the following examples of potential applications enabled by Wormhole: -
-
+- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -🛠 **Wormhole products used:** +## Explore -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Discover more about the Wormhole ecosystem, components, and protocols: -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -
-
+Demos offer more realistic implementations than tutorials: -## Decentralized Social Platforms +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -Enable seamless communication and asset transfer across decentralized social networks. + -🛠 **Wormhole products used:** +!!! note + Wormhole Integration Complete? -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -
-
+## Supported Networks by Product +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -## Memecoin Launchpads +# Security -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -🛠 **Wormhole products used:** +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +In summary: -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -
-
+Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -## Cross-Chain Perpetuals +### Governance -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -🛠 **Wormhole products used:** +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +Via governance, the Guardians can: -
-
+- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -## Gas Abstraction +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: -🛠 **Wormhole products used:** +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +## Asset Layer Protections -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -
-
+## Open Source -## Bridging Intent Library +Wormhole builds in the open and is always open source. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -
-
+## Audits -🛠 **Wormhole products used:** +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -
-
+## Bug Bounties +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -
-
+Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -## Multichain Prediction Markets +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -
-
+## Learn More -🛠 **Wormhole products used:** +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +# Get Started with the Solidity SDK -
-
+The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. +## Install the SDK -
-
+Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -## Cross-Chain Payment Widgets +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +## Key Components -
-
+The following key components and features work together to make your on-chain Wormhole integration easier to build. -🛠 **Wormhole products used:** +??? interface "Base contracts" -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers + Leverage base contracts to send and receive messages and tokens. -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -
-
+??? interface "Interfaces" + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -
-
+ - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -## Oracle Networks +??? interface "Constants" -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -
-
+ - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -🛠 **Wormhole products used:** +## Example Usage -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +### Prerequisites +Before you begin, ensure you have the following: -
-
+- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer +### Set Up a Project -
-
+Follow these steps to prepare your development environment: -## Cross-Chain Staking +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -Enable users to stake assets on one chain while earning rewards or securing networks on another. + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -
-
+2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -🛠 **Wormhole products used:** + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -
-
---- END CONTENT --- + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -## Reference Concepts [shared: true] + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` ---- + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -## List of shared concept pages: +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. +## Use Contracts to Transfer USDC -## Full content for shared concepts: +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- + ```bash + touch script/transfer.ts + ``` -# Reference +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -## Get Started +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -
+ // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - --- + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); - --- + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -2836,7 +3166,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -2891,7 +3221,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -3107,262 +3437,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -3374,7 +3538,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -3549,7 +3713,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -3630,4 +3794,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-settlement.txt b/llms-files/llms-settlement.txt index daa67f967..f96518ed9 100644 --- a/llms-files/llms-settlement.txt +++ b/llms-files/llms-settlement.txt @@ -13,52 +13,14 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/overview.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/liquidity-layer.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/solver.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/concepts/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/overview.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement -description: Learn about Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. -categories: Settlement, Transfer ---- - -# Wormhole Settlement - -## Get Started - -This section covers Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. - -
- -- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. - - [:custom-arrow: Learn more about Wormhole Settlement](/docs/learn/transfers/settlement/overview/) - -- :octicons-question-16:{ .lg .middle } **Protocol Architectures** - - --- - - Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP — for scalable, efficient cross-chain asset transfers. - - [:custom-arrow: Discover protocol architectures](/docs/learn/transfers/settlement/architecture/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/architecture/ +Doc-Content: https://wormhole.com/docs/products/settlement/concepts/architecture/ --- BEGIN CONTENT --- --- title: Settlement Protocol Architecture @@ -82,7 +44,7 @@ Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster- Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. -![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/learn/transfers/settlement/architecture/architecture-1.webp) +![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/products/settlement/concepts/architecture/architecture-1.webp) The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. @@ -124,7 +86,7 @@ First, they lack a competitive price discovery mechanism as limit order prices a Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. -![Mayan Swift - Intent-centric design](/docs/images/learn/transfers/settlement/architecture/architecture-2.webp) +![Mayan Swift - Intent-centric design](/docs/images/products/settlement/concepts/architecture/architecture-2.webp) ### Protocol Flow: How It Works @@ -143,7 +105,7 @@ Mayan Swift addresses these limitations by implementing competitive on-chain Eng Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. -![Mayan MCTP diagram](/docs/images/learn/transfers/settlement/architecture/architecture-3.webp) +![Mayan MCTP diagram](/docs/images/products/settlement/concepts/architecture/architecture-3.webp) ### Protocol Flow: How It Works @@ -154,101 +116,17 @@ Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash -2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} +2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} 3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. ## Where to Go Next -- To learn more about available EVM functions, see the [Build on the Wormhole Liquidity Layer](/docs/build/transfers/settlement/liquidity-layer/){target=\_blank} guide - To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/overview/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement Overview -description: Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. -categories: Settlement, Transfer ---- - -# Wormhole Settlement Overview - -## Introduction - -Wormhole Settlement is a fast, institutional-scale digital asset settlement — a new way to transfer assets across chains. - -With Wormhole Settlement, an intent-based asset transfer for individual users and institutions, you can swap, bridge, and build across multiple chains. You can implement cross-chain functionality within your dApps extremely simply and without compromising user experience, widening the horizons of your product offerings and the number and type of users you can cater to. - -The Settlement supports Ethereum, Ton, Optimism, Arbitrum, Base, Avalanche, Unichain, Polygon, Solana, and Sui, with many more on the horizon. It is powered by Wormhole Messaging, Wormhole Native Token Transfer (NTT), and Circle's CCTP and built in collaboration with the intent experts at Mayan Finance. - -Settlement represents Wormhole's first step towards optimizing the bridging experience and building a product that users and institutions use daily. Use it to send assets between chains, rebalance institutional inventories on-chain cheaply and quickly, or allow your application to be accessible by any user no matter what assets they hold or what chain they call home. - -## Key Features - -- **Integrator flexibility** - apps leveraging the SDK can select any one of three potential routes surfaced, each with its tradeoffs concerning time vs cost; they may extend this to users as well -- **Scalable liquidity** - taking into account the sometimes idiosyncratic yet sharp inflows into the Solana ecosystem, the hub-spoke model of the Wormhole Liquidity Layer and the flexible design of Swift are designed for capital efficiency -- **Arbitrary payload support** - integrators can bundle `callData` containing arbitrary protocol actions to enable seamless one-click user experiences, such as swap plus stake - -## Integrator Paths - -### SDK Integrators - -Wormhole provides an SDK that enables apps to abstract away the complexity of cross-chain token swaps. The SDK handles route discovery, fee estimation, and transaction construction. Apps can embed this feature in their backend or create an interface for users to bridge into their respective ecosystems quickly. - -### NTT Integrators - -NTT partners, current and future, can leverage Wormhole Settlement for near-instant NTT transfers from any chain, including Ethereum mainnet and its L2s. This eliminates waiting for slow source chain confirmation times (sometimes 15 minutes or more). If interested, please [fill out this interest form](https://wormhole.com/contact){target=\_blank}. - -### Chain Integrators - -Due to the hub-spoke model of liquidity, new chains without proven traction can access the same level of liquidity for cross-chain intent fulfillment from day one of mainnet launch as established ecosystems with clear evidence of adoption. - -!!!tip - Looking to integrate Wormhole Settlement? If you're ready, check out how to [integrate Wormhole Settlement Routes using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank}. - -## Related Resources - -- To learn more about the architecture of Wormhole-native swap protocols, see the [Settlement Protocol Architectures](/docs/learn/transfers/settlement/architecture/){target=\_blank} page ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement -description: Start building with Wormhole Settlement; integrate with the Liquidity Layer and set up Solvers to enable seamless cross-chain asset transfers. -categories: Settlement, Transfer ---- - -# Wormhole Settlement - -## Get Started - -This section provides resources to build with Wormhole Settlement, including integrating the Liquidity Layer into your application and running a Solver for efficient cross-chain asset transfers. - -
- -- :octicons-code-16:{ .lg .middle } **Build on the Liquidity Layer** - - --- - - Integrate seamlessly with Wormhole's Liquidity Layer, learn key EVM contract functions for fast and secure cross-chain transfers. - - [:custom-arrow: Build on the Liquidity layer](/docs/build/transfers/settlement/liquidity-layer/) - -- :octicons-code-16:{ .lg .middle } **Run a Settlement Solver** - - --- - - Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. - - [:custom-arrow: Run a Solver](/docs/build/transfers/settlement/solver/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/faqs/ +Doc-Content: https://wormhole.com/docs/products/settlement/faqs/ --- BEGIN CONTENT --- --- title: Wormhole Settlement FAQs @@ -273,349 +151,357 @@ After the user receives the token upfront, the execution of additional contract If the slippage tolerance is set too low, the user may receive USDC on the destination chain instead of the intended swap outcome. However, the four basis points (bps) fee is non-refundable, as the service provided by Liquidity Layer (LL) solvers (ensuring front-finality) is separate from the composing protocol's services, such as swaps or deposits. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/liquidity-layer/ +Doc-Content: https://wormhole.com/docs/products/settlement/get-started/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Liquidity Layer -description: Learn how to build on the Wormhole Liquidity Layer, the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. +title: Get Started +description: Perform a cross-chain token swap using Wormhole Settlement and the Mayan Swift route with the TypeScript SDK on mainnet. categories: Settlement, Transfer --- -# Build on the Wormhole Liquidity Layer - -## Introduction - -The Wormhole Liquidity Layer is the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. It allows these protocols to bundle call data containing arbitrary actions that can be executed atomically alongside each transfer. This feature enables developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. The following section describes the key smart contract components for teams seeking to build atop Wormhole Settlement. - -## EVM Functions - -The EVM Token Router is a simple interface against which to integrate. For an integrator, the contracts have two main entry points: `placeMarketOrder` and `placeFastMarketOrder`. - -See the complete list of [Token Router contract addresses](/docs/build/reference/contract-addresses/#settlement-token-router){target=\_blank} for supported networks. +# Get Started -### Fast Market Order +[Settlement](/docs/products/settlement/overview/){target=\_blank} is Wormhole’s intent-based execution layer, enabling fast, multichain token transfers. It coordinates routing logic, relayers, and on-chain infrastructure to let users express what they want to be done, not how. -The `placeFastMarketOrder` function allows the caller to elect for a _faster-than-finality_ transfer of USDC (with an arbitrary message payload) to the destination chain by setting the `maxFee` and `deadline` parameters. Using this interface does not guarantee that the caller's transfer will be delivered faster than finality; however, any willing market participants can compete for the specified `maxFee` by participating in an auction on the Solana `MatchingEngine` +This guide walks you through performing a real token swap using the [Mayan Swift route](https://mayan.finance){target=_blank}, one of the three integrated Settlement protocols, with the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=_blank}. -```solidity title="`placeFastMarketOrder` Interface" -function placeFastMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, - uint128 maxFee, - uint32 deadline -) external payable returns (uint64 sequence, uint64 fastSequence); -``` - -??? interface "Parameters `placeFastMarketOrder()`" - - `amountIn` ++"uint128"++ - - The amount to transfer. - - --- - - `targetChain` ++"uint16"++ +By the end, you'll have a working script that: - Target chain ID. +- Resolves token transfer routes using Mayan Swift +- Quotes and validates the best route +- Initiates a swap on a source chain and completes the transfer on a destination chain - --- - - `redeemer` ++"bytes32"++ - - Redeemer contract address. - - --- +!!! note + Mayan Swift currently supports **mainnet only**. Attempting to run this demo on a testnet will fail. - `redeemerMessage` ++"bytes"++ +## Prerequisites - An arbitrary payload for the redeemer. +Before you begin, ensure you have the following: - --- +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#settlement){target=\_blank} - `maxFee` ++"uint128"++ +This example uses Ethereum as the source chain and Solana as the destination. As a result, you'll need an Ethereum wallet with ETH for gas and a Solana wallet with SOL for fees. You can adapt the example to match your preferred chains. - The maximum fee the user wants to pay to execute a fast transfer. +## Set Up a Project - --- +Start by scaffolding a basic Node.js project and installing the required SDKs. - `deadline` ++"uint32"++ +1. Create a new project folder: - The deadline for the fast transfer auction to start. Note: This timestamp should be for the `MatchingEngine` chain (such as Solana) to avoid any clock drift issues between different blockchains. Integrators can set this value to `0` if they don't want to use a deadline. + ```bash + mkdir settlement-swap + cd settlement-swap + npm init -y + ``` -The `placeFastMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. +2. Install the required dependencies: -### Market Order + ```bash + npm install @wormhole-foundation/sdk-connect \ + @wormhole-foundation/sdk-evm \ + @wormhole-foundation/sdk-solana \ + @mayanfinance/wormhole-sdk-route \ + dotenv + npm install -D typescript tsx + ``` -The `placeMarketOrder` function is a _wait-for-full-finality_ USDC transfer with an arbitrary message payload. The Swap Layer, built on top of the Wormhole Settlement, uses this function if the auction on the matching engine for `placeFastMarketOrder` doesn't start within a specific deadline. +3. Create the file structure: -```solidity title="`placeMarketOrder` Interface" -function placeMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, -) external payable returns (uint64 sequence, uint64 protocolSequence); -``` + ```bash + mkdir src + touch src/helpers.ts src/swap.ts .env .gitignore + ``` -??? interface "Parameters `placeMarketOrder()`" +4. Set up secure access to your wallets. This guide assumes you are loading your `MAINNET_ETH_PRIVATE_KEY` and `MAINNET_SOL_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [cast wallet](https://book.getfoundry.sh/reference/cast/cast-wallet/){target=_blank}. + + !!! warning + If you use a .env file during development, add it to your .gitignore to exclude it from version control. Never commit private keys or mnemonics to your repository. + +## Perform a Token Swap + +This section shows you how to perform a token swap using the Mayan Swift route. You will define a helper function to configure the source and destination chain signers. + +Then, you'll create a script that initiates a transfer on Ethereum, uses the Mayan Swift resolver to find valid routes, sends the transaction, and completes the transfer on Solana. + +1. Open `helper.ts` and define the `getSigner` utility function to load private keys, instantiate signers for Ethereum and Solana, and return the signers along with the Wormhole-formatted address: + + ```ts title="src/helpers.ts" + import { + Chain, + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, +} from '@wormhole-foundation/sdk-connect'; +import { getEvmSignerForKey } from '@wormhole-foundation/sdk-evm'; +import { getSolanaSigner } from '@wormhole-foundation/sdk-solana'; + +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (MAINNET_ETH_PRIVATE_KEY, MAINNET_SOL_PRIVATE_KEY) + * must be loaded securely beforehand, for example via a keystore, + * secrets manager, or environment variables (not recommended). + */ +// Define Transfer Interface +export interface SignerContext { + signer: Signer; + address: ChainAddress; +} - `amountIn` ++"uint128"++ +export async function getSigner( + chain: ChainContext +): Promise> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + switch (platform) { + case 'Solana': + signer = await getSolanaSigner( + await chain.getRpc(), + getEnv('MAINNET_SOL_PRIVATE_KEY') + ); + break; + case 'Evm': + signer = await getEvmSignerForKey( + await chain.getRpc(), + getEnv('MAINNET_ETH_PRIVATE_KEY') + ); + break; + default: + throw new Error('Unrecognized platform: ' + platform); + } + + return { + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` - The amount to transfer. +2. In `swap.ts`, add the following script, which will handle all of the logic required to perform the token swap: + + ```ts title="src/swap.ts" + import { Wormhole, routes } from '@wormhole-foundation/sdk-connect'; +import { EvmPlatform } from '@wormhole-foundation/sdk-evm'; +import { SolanaPlatform } from '@wormhole-foundation/sdk-solana'; +import { MayanRouteSWIFT } from '@mayanfinance/wormhole-sdk-route'; +import { getSigner } from './helpers'; + +(async function () { + // Setup + const wh = new Wormhole('Mainnet', [EvmPlatform, SolanaPlatform]); + + const sendChain = wh.getChain('Ethereum'); + const destChain = wh.getChain('Solana'); + + // To transfer native ETH on Ethereum to native SOL on Solana + const source = Wormhole.tokenId(sendChain.chain, 'native'); + const destination = Wormhole.tokenId(destChain.chain, 'native'); + + // Create a new Wormhole route resolver, adding the Mayan route to the default list + // @ts-ignore: Suppressing TypeScript error because the resolver method expects a specific type, + // but MayanRouteSWIFT is compatible and works as intended in this context. + const resolver = wh.resolver([MayanRouteSWIFT]); + + // Show supported tokens + const dstTokens = await resolver.supportedDestinationTokens( + source, + sendChain, + destChain + ); + console.log(dstTokens.slice(0, 5)); + + // Load signers and addresses from helpers + const sender = await getSigner(sendChain); + const receiver = await getSigner(destChain); + + // Creating a transfer request fetches token details + // since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source, + destination, + }); + + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + const bestRoute = foundRoutes[0]!; + + // Specify the amount as a decimal string + const transferParams = { + amount: '0.002', + options: bestRoute.getDefaultOptions(), + }; + + // Validate the queries route + let validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) { + console.error(validated.error); + return; + } + console.log('Validated: ', validated); + + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) { + console.error(`Error fetching a quote: ${quote.error.message}`); + return; + } + console.log('Quote: ', quote); + + // Initiate the transfer + const receipt = await bestRoute.initiate( + tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); + + await routes.checkAndCompleteTransfer( + bestRoute, + receipt, + receiver.signer, + 15 * 60 * 1000 + ); +})(); + ``` - --- +3. Execute the script to initiate and complete the transfer: - `targetChain` ++"uint16"++ + ```bash + npx tsx src/swap.ts + ``` - Target chain ID. + If successful, you’ll see terminal output like this: + +
+npx tsx src/swap.ts +Validated: { valid: true, ... } +Quote: { success: true, ... } +Initiated transfer with receipt: ... +Checking transfer state... +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: DestinationFinalized + +
- --- +Congratulations! You've just completed a cross-chain token swap from Ethereum to Solana using Settlement. - `redeemer` ++"bytes32"++ +## Customize the Integration - Redeemer contract address. +You can tailor the example to your use case by adjusting: - --- +- **Tokens and chains**: Use `getSupportedTokens()` to explore what's available. +- **Source and destination chains**: Modify `sendChain` and `destChain` in `swap.ts`. +- **Transfer settings**: Update the amount or route parameters. +- **Signer management**: Modify `src/helpers.ts` to integrate with your preferred wallet setup. - `redeemerMessage` ++"bytes"++ +## Next Steps - An arbitrary payload for the redeemer. +Once you've chosen a path, follow the corresponding guide to start building: -The `placeMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. +- [**`demo-mayanswift`**](https://github.com/wormhole-foundation/demo-mayanswift){target=_blank}: Check out the repository for the full code example. + --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/solver/ +Doc-Content: https://wormhole.com/docs/products/settlement/overview/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Solver -description: Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. +title: Settlement Overview +description: Discover how Settlement enables fast, intent-based token transfers across chains using a unified system of solver auctions and integrated execution routes. categories: Settlement, Transfer --- -# Run a Wormhole Settlement Solver - -## Introduction - -This page provides instructions on how to set up, configure, and run a Solver for Wormhole Settlement using the [example solver](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/update-solver-example/solver){target=\_blank}. - -A Solver is an off-chain agent responsible for: - -- Listening to cross-chain transfer requests sent over Wormhole -- Bidding in auctions (on Solana) to fulfill each request -- Facilitating the actual cross-chain transfer by locking/burning assets on Solana and minting/unlocking them on the destination chain -- Rebalancing once the origin chain transaction finalizes and is redeemed back on Solana - -For information on how the protocol functions and its core features, please visit the [Wormhole Settlement](/docs/learn/transfers/settlement/overview/){target=\_blank} page. - -## Background - -The Solana Matching Engine's permissionless English auction is a central component of Wormhole Settlement protocol architecture. The Matching Engine contract allows any third-party solver to interact with the matching engine to place bids or improve existing ones. The contract includes four key instructions: - -1. `initialize_auction` - creates a new auction account on-chain and sets basic parameters like the auction's token mint, the amount required, and the bidding period details -2. `bid` - allows a solver to place or update a bid on the active auction -3. `finalize_auction` - following the conclusion of the auction, this instruction completes the fast transfer by sending funds to the recipient on the target chain. This instruction may call the Circle CCTP contract or release an NTT contract in the future, depending on the shuttle asset in question. Failure to execute this message within a predefined grace period may result in a penalty for the winning bidder. -4. `cancel_auction` - cancels an open auction when the auction is no longer valid or was created by mistake. The program returns all locked funds to their respective owners - -These instructions work together to carry out the auction as follows: - -- The solver transfers the bid amount to the program escrow account, which ensures they have liquidity -- With each successful call of `bid`, the program updates the auction to the new highest bidder, and the prior bid is atomically sent back to the originating solver -- The originating solver can repurpose the returned funds and use them to improve their bid -- Following the auction, the winning solver has to call an instruction on the matching engine to execute the intent - -When placing a bid, whether initial or improved, the solver must deposit the required funds plus a security deposit into the matching engine contract. In this permissionless auction, the requirement of this principal amount plus the security deposit ensures a solver's credible commitment to fulfill the transfer. Malicious actors could place hollow bids without this safeguard, undermining the auction's credibility and hindering true price discovery. +# Settlement Overview -If the winning solver fails to call the `finalize_auction` instruction, other competing solvers may permissionlessly 'slash' the solver by executing the instruction on their behalf and collecting a portion of the original security deposit as a reward. The remaining portion is routed to the user as compensation for the unanticipated delay. This mechanism properly incentivizes timely execution through solver redundancy and competition. +Wormhole Settlement is a multichain transfer system that allows users to specify what they want to happen, such as sending or swapping tokens, without handling the execution themselves. Instead, off-chain agents called solvers compete to fulfill these user intents. -## Testnet Example Solver +Settlement prioritizes speed, execution quality, and reliability. Its primary route, Mayan Swift, leverages fast off-chain auctions among a curated set of solvers to achieve low-latency bridging with minimal slippage. All settlement steps remain verifiable on-chain through Wormhole messages. -You can clone the Wormhole [`example-liquidity-layer`](https://github.com/wormholelabs-xyz/example-liquidity-layer){target=\_blank} repository to use the included [`solver`](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/main/solver){target=\_blank} directory as an example solver to fulfill fast orders by interacting with the Matching Engine on Solana. +For broader use cases and protocol-level execution, Mayan MCTP provides an alternative path. It wraps Circle’s CCTP to facilitate native USDC bridging and token delivery in a single, verifiable flow. While slower due to chain finality constraints, MCTP offers a reliable mechanism for cross-chain transfers. -!!!warning - This example is not optimized for performance, has only been tested on Solana devnet, and is not intended for production use. Any assumptions made in this example may not translate to mainnet. - -### Prerequisites - -In order to build and install dependencies locally in this repo, you will need: - -- node v20.18.1 -- npmv - get started by installing `nvm` using this [installation guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating){target=\_blank} - -Navigate into the `solver` directory, then run the command below to set up your environment and install the node dependencies and Matching Engine package: - -```sh -make dependencies -``` - -### Set up Config - -The following is an example of a `config.json` file for Solana devnet. The keys here are required for both the publisher and example solver processes. - -```json title="config.json" -{ - "environment": "Testnet", - "zmqChannels": { - "fastVaa": "tcp://localhost:6001", - "finalizedVaa": "tcp://localhost:6002" - }, - "publisher": { - "log": { - "level": "info" - }, - "vaaSpy": { - "host": "localhost:7073", - "enableObservationCleanup": true, - "observationSeenThresholdMs": 1500000, - "observationCleanupIntervalMs": 500, - "observationsToRemovePerInterval": 5, - "delayedThresholdMs": 60000 - } - }, - "solver": { - "log": { - "level": "info", - "filename": "logs/solver.log" - }, - "connection": { - "rpc": "", - "maxTransactionsPerSecond": 5, - "commitment": "processed", - "addressLookupTable": "YourAddressLookupTab1eHere11111111111111111", - "matchingEngine": "mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS", - "mint": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", - "knownAtaOwners": [ - "Payer11111111111111111111111111111111111111", - "Payer11111111111111111111111111111111111112", - "Payer11111111111111111111111111111111111113" - ] - } - }, - "routerEndpoints": [ - { - "chain": "Sepolia", - "endpoint": "0xE57D917bf955FedE2888AAbD056202a6497F1882", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Avalanche", - "endpoint": "0x8Cd7D7C980cd72eBD16737dC3fa04469dcFcf07A", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "OptimismSepolia", - "endpoint": "0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "ArbitrumSepolia", - "endpoint": "0xe0418C44F06B0b0D7D1706E01706316DBB0B210E", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "BaseSepolia", - "endpoint": "0x824Ea687CD1CC2f2446235D33Ae764CbCd08e18C", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Polygon", - "endpoint": "0xa098368AaaDc0FdF3e309cda710D7A5f8BDEeCD9", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - } - ] -} -``` - -The rollback risks and offer edges configured in the sample config are arbitrary placeholders. You should use historical data and your risk tolerance, to determine appropriate values for your project. - -### Listen to Activity +## Key Features -The example solver listens to attested Wormhole messages (VAAs) published on the Wormhole Guardian gossip network. To listen to this gossip network and run the VAA publisher, run the command below. Docker compose is used to listen to the Pyth Beacon and start the [`publishActivity`](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/publishActivity.ts){target=\_blank} process. +- **Intent-based architecture**: Users express what they want to happen (e.g., swap X for Y on chain Z), and solvers execute it. +- **Solver auctions**: Solvers compete in on-chain auctions for the right to fulfill intents, improving execution quality. +- **Fast and fallback-capable**: Combines high-speed execution with a reliable fallback path. +- **Minimal slippage**: Settlement abstracts away complex balancing operations and uses shuttle assets like USDC and tokens deployed via NTT. +- **On-chain verifiability**: Even though auctions are off-chain, all settlement steps remain verifiable on-chain via Wormhole messages. +- **Two integrated routes**: Mayan Swift for speed, Mayan MCTP for compatibility and redundancy. -```sh -NETWORK=testnet CONFIG=path/to/config.json make run-publisher -``` +## How It Works -You should see output resembling: +At the core of Settlement are two components: -
- Start logging with info level. - 2025-01-21 16:38:28.145 [publisher] info: Environment: Testnet - 2025-01-21 16:38:36.631 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33635, vaaTime=1737499116 - 2025-01-21 16:38:51.044 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33637, vaaTime=1737499130 - 2025-01-21 16:40:24.890 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33639, vaaTime=1737499224 -
+- **Intents**: Signed transactions where a user defines what outcome they want (e.g., send USDC to another chain and receive ETH). It abstracts what the user wants, not how it should be executed. +- **Solvers**: Third-party agents that compete in auctions to fulfill these intents. They front capital, perform swaps or transfers, and receive fees in return. -To set up the Pyth Beacon (which is run using make `run-publisher`), you may need to increase the UDP buffer size for the OS: +Settlement currently supports the following integrated protocols. -=== "Linux" +### Mayan Swift - ```sh - sudo sysctl -w net.core.rmem_max=2097152 - sudo sysctl -w net.core.rmem_default=2097152 - ``` +Mayan Swift implements a traditional intent-based architecture, where solvers compete to fulfill user intents by utilizing their inventory. It offers fast execution, typically around 12 seconds. To participate, solvers must hold assets on multiple chains, which can lead to imbalances: some chains may get depleted while others accumulate excess. This requires occasional rebalancing and adds operational overhead. Despite that, Mayan Swift is ideal for high-speed transfers and benefits from open, competitive auctions that can drive down execution prices. -=== "MacOS" +The diagram below shows how Mayan Swift handles a cross-chain intent when a user wants to swap ARB on Arbitrum for WIF on Solana. Behind the scenes, the process is more involved and relies on solver-managed liquidity across both chains. - ```sh - sudo sysctl -w net.inet.udp.recvspace=2097152 - ``` +1. **Solver initiates on Arbitrum**: Solver swaps ARB → ETH and deposits ETH into an escrow on Arbitrum. +2. **VAA emitted to Solana**: A [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} triggers the solver to release SOL on Solana, which is swapped to WIF using an aggregator. +3. **User receives WIF**: Once the user receives WIF, a second VAA is emitted to finalize the transfer and releases the ETH held in the escrow to the solver. +4. **Failure handling**: If any step fails, the ETH in escrow is either retained or returned to the user — the solver only gets paid if execution succeeds. -### Running the Example Solver +```mermaid +sequenceDiagram + participant User + participant Solver_ARB as Solver (Arbitrum) + participant Escrow + participant Wormhole + participant Solver_SOL as Solver (Solana) + participant Aggregator -Using the same config for your publisher, run the example solver with the command below. + Note over User,Aggregator: User has ARB and wants WIF -```sh -CONFIG=path/to/config.json make run-solver + User->>Solver_ARB: Submit intent (ARB → WIF) + Solver_ARB->>Escrow: Swaps ARB → ETH and deposits ETH + Escrow-->>Wormhole: Emits VAA + Wormhole-->>Solver_SOL: Delivers VAA + Solver_SOL->>Aggregator: Releases SOL and swaps to WIF + Aggregator->>Solver_SOL: Receives WIF + Solver_SOL->>User: Sends WIF + User-->>Wormhole: Emits final VAA + Wormhole-->>Escrow: Confirms receipt + Escrow->>Solver_ARB: Releases ETH to solver ``` -It is recommended you write log output to a file so errors can be tracked. The example config above specifies an example log filename. - -This process reads the following environment variables: - -```sh -SOLANA_PRIVATE_KEY_1= -SOLANA_PRIVATE_KEY_2= -SOLANA_PRIVATE_KEY_3= -SOLANA_PRIVATE_KEY_4= -SOLANA_PRIVATE_KEY_5= -``` +### Mayan MCTP -At least one of these environment variables must be defined as a keypair encoded in base64 format. These payers must have SOL to send transactions on Solana devnet. If they need funds, they can request them from the [Solana devnet faucet](https://faucet.solana.com/){target=\_blank}. +Mayan MCTP is a fallback protocol that wraps Circle’s CCTP into the Settlement framework. It bundles USDC bridging and swaps into a single operation handled by protocol logic. This route is slower due to its reliance on chain finality. However, it provides broad compatibility and redundancy, making it useful when faster routes are unavailable or when targeting chains that aren’t supported by Swift. While typically more expensive due to protocol fees, it ensures reliable settlement when faster options are unavailable. -The example solver assumes that these payers own USDC Associated Token Accounts(ATAs), which will be used to fulfill fast transfers. These ATAs must be funded with Solana Devnet USDC. If your ATAs need funds, request some at the [Circle testnet faucet](https://faucet.circle.com/){target=\_blank}. +## Use Cases -Wallets and their corresponding ATA will be disabled if there are insufficient funds to pay for transactions or fulfill fast transfers. These constraints can be modified using the `updatePayerMinimumLamports` and `updateTokenMinimumBalance` methods. +- **Cross-Chain Perpetuals** -An address lookup table is required to execute some transactions. Use the command below to create one. + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Provides fast token execution across chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch live prices and manage position state across chains. -```sh -CONFIG=path/to/config.json make create-lut -``` +- **Bridging Intent Library** -`SOLANA_PRIVATE_KEY_1` must be defined for this script to work. + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Handles user-defined bridge intents. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Triggers cross-chain function calls. -The example solver has the following toggles depending on which orders you want to fulfill: +- **Multichain Prediction Markets** -- `enableCctpOrderPipeline()` -- `enableLocalOrderPipeline()` -- `enablePlaceInitialOffer()` -- `enableImproveOffer()` + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Executes token flows between chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Gets market data and tracks state. -See the comments in [runExampleSolver](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/runExampleSolver.ts){target=\_blank} for more information. +## Next Steps -This example solver does NOT do the following: +Start building with Settlement or dive deeper into specific components: -- Discriminate between the CCTP source networks. You must add logic to determine whether you want to constrain fulfilling orders from specific networks. This solver will try to fulfill all orders as long as `enableCctpOrderPipeline()` is called -- Discriminate among fulfillment sizes. No logic determines how small or large fast order transfer sizes should be. This solver will try to fulfill anything as long as your balance can handle it -- Add auctions to auction history. We recommend that after settling a complete auction (one that you have won), you write the auction pubkey to a database and have a separate process to add auction history entries to reclaim rent from these auction accounts. The auction history time delay is two hours after the VAA timestamp. This example does not prescribe any specific database, so add whichever you want +- **[Get Started with Settlement](/docs/products/settlement/get-started/)**: Follow a hands-on demo using Mayan Swift. +- **[Architecture Documentation](/docs/products/settlement/concepts/architecture/)**: Explore the Settlement architecture and components. --- END CONTENT --- ## Basics Concepts [shared: true] @@ -632,2090 +518,2485 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary +# Get Started with Messaging -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Chain ID +## Prerequisites -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +Before you begin, ensure you have the following: -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -## Consistency Level +## Configure Your Messaging Environment -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a directory and initialize a Node.js project: -## Delivery Provider + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Emitter + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Finality + ```bash + npx tsc --init + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + Make sure your `tsconfig.json` includes the following settings: -## Guardian + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Guardian Network + ```bash + npm install @wormhole-foundation/sdk + ``` -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. Create a new file named `main.ts`: -## Guardian Set + ```bash + touch main.ts + ``` -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Heartbeat + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -## Observation + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -## Relayer + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -A relayer is any process that delivers VAAs to a destination. +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -## Sequence + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +2. Run the script using the following command: -## Spy + ```bash + npx tsx main.ts + ``` -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-## VAA +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -## Validator +## Next Steps -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Infrastructure Components +# Get Started with Core Contracts -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +## Introduction -## Get Started +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -Start here for an overview of Wormhole architecture components and security mechanisms: +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -
+This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Prerequisites - --- +To interact with the Wormhole Core Contract, you'll need the following: - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +## How to Interact with Core Contracts -- :octicons-book-16:{ .lg .middle } **Security** +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - --- +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. - [:custom-arrow: Learn About Security](/docs/learn/security/) +### Sending Messages -
+To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -## Explore Components +=== "EVM" -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. - -## Next Steps - -
- -- :octicons-book-16:{ .lg .middle } **Messaging Components** - - --- - - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) - -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** - - --- - - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. - - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- - -# Architecture - -## Overview - -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. - -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) - -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: - -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract - -## On-Chain Components - -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract - -## Off-Chain Components - -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers - -## Next Steps - -
- -- :octicons-book-16:{ .lg .middle } **Core Contracts** - - --- - - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) - -- :octicons-tools-16:{ .lg .middle } **Core Messaging** - - --- - - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. - - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- - -# Core Contracts - -## Introduction - -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. - -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. - -## Key Functions - -Key functions of the Wormhole Core Contract include the following: - -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time - -## How the Core Contract Works - -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. - -The following describes the role of the Wormhole Core Contract in message transfers: - -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions - -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. - -### Message Submission - -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: - -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page - -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. - -### Message Reception + ??? interface "Parameters" -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -## Multicast + --- -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + --- -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + ??? interface "Returns" -## Next Steps + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -
+ ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - --- +// Check fee and send parameters - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` - --- + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. +=== "Solana" - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -
---- END CONTENT --- + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Parameters" -## Guardian + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -Guardians fulfill their role in the messaging protocol as follows: + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). + ??? child "Type `PostMessage<'info>`" -## Guardian Network + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -The Guardian Network is designed to help Wormhole deliver on five key principles: + --- -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing + `batch_id` ++"u32"++ + + An identifier for the message batch. -The following sections explore each principle in detail. + --- -### Decentralization + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. + --- -Two common approaches to decentralization have notable limitations: + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -To answer that, consider these key constraints and design decisions: +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -### Modularity +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -### Chain Agnosticism +### Receiving Messages -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +The way a message is received and handled depends on the environment. -### Scalability +=== "EVM" -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. + ??? interface "Parameters" -### Upgradeable + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -Wormhole is designed to adapt and evolve in the following ways: + ??? interface "Returns" -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + ??? child "Struct `VM`" -## Next Steps + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -
+ For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -- :octicons-book-16:{ .lg .middle } **Relayers** + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- - --- + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. + ??? interface "Example" - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + // Perform safety checks here - --- + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + // Your custom application logic here +} + ``` - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -
---- END CONTENT --- +=== "Solana" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -# Relayers + Retrieve the raw message data: -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. + ??? interface "Example" -There are three primary types of relayers discussed: + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +#### Validating the Emitter -## Fundamentals +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -Key characteristics of VAAs include: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- Public emission from the Guardian Network +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -- Authentication through signatures from the Guardian Network +await tx.wait(); +``` -- Verifiability by any entity or any Wormhole Core Contract +#### Additional Checks -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Keep in mind the following security considerations around relayers: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +## Source Code References -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -## Client-Side Relaying +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -### Key Features +# Wormhole Relayer -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +## Introduction -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -### Implementation +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -Users themselves carry out the three steps of the cross-chain process: +## Get Started with the Wormhole Relayer -1. Perform an action on chain A +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -2. Retrieve the resulting VAA from the Guardian Network +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -3. Perform an action on chain B using the VAA +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-### Considerations +### Wormhole Relayer Interfaces -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -- Users must sign all required transactions with their own wallet +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- Users must have funds to pay the transaction fees on every chain involved +## Interact with the Wormhole Relayer -- The user experience may be cumbersome due to the manual steps involved +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -## Custom Relayers +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +Your initial set up should resemble the following: -### Key Features +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +contract Example { + IWormholeRelayer public wormholeRelayer; -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -### Implementation +### Send a Message -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -### Considerations +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -- Development work and hosting of relayers are required +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -## Wormhole Relayers +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -### Key Features +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +### Receive a Message -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -### Implementation +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -The Wormhole relayer integration involves two key steps: +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +## Delivery Guarantees -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -### Considerations +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -- All computations are performed on-chain +## Delivery Statuses -- Potentially less gas-efficient compared to custom relayers +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- Support may not be available for all chains +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -## Next Steps +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -
+All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -- :octicons-book-16:{ .lg .middle } **Spy** +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. - --- +## Other Considerations - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +## Track the Progress of Messages with the Wormhole CLI - --- +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +=== "Mainnet" - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +=== "Testnet" - --- + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Step-by-Step Tutorial -
+For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. categories: Basics --- -# Spy +# Messaging Overview -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Key Features -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -## Key Features +## How It Works -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +The messaging flow consists of several core components: + +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -## Integrator Use Case +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +## Use Cases -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -## Observable Message Categories +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -A Spy can access the following categories of messages shared over the gossip protocol: + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +- **Gas Abstraction** - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +- **Bridging Intent Library** - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -## Additional Resources +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -
+ - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +## Next Steps - --- +Follow these steps to work with Wormhole Messaging: - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +# Products - --- +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +## Transfer Products - --- +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +
-
+::spantable:: -## Next Steps +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | -
+::end-spantable:: -- :octicons-code-16:{ .lg .middle } **Run a Spy** +
- --- +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +
- [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. -- :octicons-code-16:{ .lg .middle } **Use Queries** +## Bridging UI - --- +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +## Real-time Data - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. -
+## Multichain Governance + +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Glossary -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +## Chain ID -## VAA Format +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -The basic VAA consists of header and body components described as follows: +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +## Consistency Level - Where each `signature` is: +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +## Delivery Provider -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +## Emitter -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +## Finality -## Consistency and Finality +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +## Guardian -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -## Signatures +## Guardian Network -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` +## Guardian Set -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -## Payload Types +## Heartbeat -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. -### Token Transfer +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +## Observation -Transferring tokens from the sending chain to the destination chain requires the following steps: +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +## Relayer -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +A relayer is any process that delivers VAAs to a destination. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +## Sequence -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Spy -### Attestation +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +## VAA -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -The message format for token attestation is as follows: +## Validator -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- -#### Attestation Tips +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- -Be aware of the following considerations when working with attestations: +# Architecture -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +## Overview -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. -### Token Transfer with Message + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +## On-Chain Components -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## Off-Chain Components -### Governance +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +## Next Steps -#### Action Structure +
-Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +- :octicons-book-16:{ .lg .middle } **Core Contracts** -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action + --- -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -#### Actions +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: + --- -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -## Lifetime of a Message + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +
+--- END CONTENT --- -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +# The Wormhole Ecosystem -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -## Next Steps +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-book-16:{ .lg .middle } **Guardians** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. categories: Basics --- -# Introduction to Wormhole +# Core Contracts -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +## Introduction -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +## Key Functions -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +Key functions of the Wormhole Core Contract include the following: -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## How the Core Contract Works -## What Problems Does Wormhole Solve? +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following describes the role of the Wormhole Core Contract in message transfers: -Critical problems Wormhole addresses include: +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -## What Does Wormhole Offer? +### Message Submission -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -## What Isn't Wormhole? +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +### Message Reception -## Use Cases of Wormhole +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -Consider the following examples of potential applications enabled by Wormhole: +## Multicast -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -## Explore +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -Discover more about the Wormhole ecosystem, components, and protocols: +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -## Demos +## Next Steps -Demos offer more realistic implementations than tutorials: +
-- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** - + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -!!! note - Wormhole Integration Complete? + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** + --- -## Supported Blockchains + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -Wormhole supports a growing number of blockchains. + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Security +## Guardian -## Core Security Assumptions +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Guardians fulfill their role in the messaging protocol as follows: -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -In summary: +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +## Guardian Network -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## Guardian Network +The Guardian Network is designed to help Wormhole deliver on five key principles: -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Governance +The following sections explore each principle in detail. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +### Decentralization -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +Two common approaches to decentralization have notable limitations: -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -Via governance, the Guardians can: +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +To answer that, consider these key constraints and design decisions: -## Monitoring +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +### Modularity -Guardians monitor: +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Chain Agnosticism -## Asset Layer Protections +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +### Scalability -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -## Open Source +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -Wormhole builds in the open and is always open source. +### Upgradeable -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +Wormhole is designed to adapt and evolve in the following ways: -## Audits +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +## Next Steps -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +
-## Bug Bounties +- :octicons-book-16:{ .lg .middle } **Relayers** -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + --- -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -## Learn More + --- -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Get Started with Core Contracts +# Relayers -## Introduction +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +There are three primary types of relayers discussed: -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -## Prerequisites +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -To interact with the Wormhole Core Contract, you'll need the following: +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +## Fundamentals -## How to Interact with Core Contracts +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +Key characteristics of VAAs include: -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- Public emission from the Guardian Network -### Sending Messages +- Authentication through signatures from the Guardian Network -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +- Verifiability by any entity or any Wormhole Core Contract -=== "EVM" +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +Keep in mind the following security considerations around relayers: - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks - ??? interface "Parameters" +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain + +## Client-Side Relaying + +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + +### Key Features + +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure + +### Implementation + +Users themselves carry out the three steps of the cross-chain process: + +1. Perform an action on chain A + +2. Retrieve the resulting VAA from the Guardian Network - --- +3. Perform an action on chain B using the VAA - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +### Considerations - --- +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- Users must sign all required transactions with their own wallet - ??? interface "Returns" +- Users must have funds to pay the transaction fees on every chain involved - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +- The user experience may be cumbersome due to the manual steps involved - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +## Custom Relayers -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -// Check fee and send parameters +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +### Key Features -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -=== "Solana" +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +### Implementation - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - ??? interface "Parameters" +### Considerations - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +- Development work and hosting of relayers are required - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - ??? child "Type `PostMessage<'info>`" +## Wormhole Relayers - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +### Key Features - --- +- **Lower operational costs** - no need to develop, host, or maintain individual relayers - `batch_id` ++"u32"++ - - An identifier for the message batch. +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - --- +### Implementation - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +The Wormhole relayer integration involves two key steps: - --- +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +### Considerations - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +- All computations are performed on-chain -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +- Potentially less gas-efficient compared to custom relayers -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- Support may not be available for all chains -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +## Next Steps -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +
-### Receiving Messages +- :octicons-book-16:{ .lg .middle } **Spy** -The way a message is received and handled depends on the environment. + --- -=== "EVM" + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - ??? interface "Parameters" + --- - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ??? interface "Returns" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - ??? child "Struct `VM`" + --- - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- +
+--- END CONTENT --- - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - ??? interface "Example" +# Spy - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - // Perform safety checks here +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - // Your custom application logic here -} - ``` +## Key Features - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure -=== "Solana" +## Integrator Use Case - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - Retrieve the raw message data: +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +## Observable Message Categories - ??? interface "Example" +A Spy can access the following categories of messages shared over the gossip protocol: - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -#### Validating the Emitter + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +## Additional Resources -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +
-```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -await tx.wait(); -``` + --- -#### Additional Checks + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + --- -## Source Code References + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + --- -# Wormhole Relayer + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -## Introduction + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +
-This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +## Next Steps -## Get Started with the Wormhole Relayer +
-Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +- :octicons-code-16:{ .lg .middle } **Run a Spy** -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. + --- -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+ Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -### Wormhole Relayer Interfaces + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +- :octicons-code-16:{ .lg .middle } **Use Queries** -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + --- -## Interact with the Wormhole Relayer + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. +
+--- END CONTENT --- -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -Your initial set up should resemble the following: +# Verified Action Approvals -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -contract Example { - IWormholeRelayer public wormholeRelayer; +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -### Send a Message +## VAA Format -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The basic VAA consists of header and body components described as follows: -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. + Where each `signature` is: -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +## Consistency and Finality -### Receive a Message +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +## Signatures -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -## Delivery Guarantees +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +## Payload Types -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -## Delivery Statuses +### Token Transfer -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Transferring tokens from the sending chain to the destination chain requires the following steps: -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -## Other Considerations +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +### Attestation -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -## Track the Progress of Messages with the Wormhole CLI +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +The message format for token attestation is as follows: -=== "Mainnet" +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +#### Attestation Tips -=== "Testnet" +Be aware of the following considerations when working with attestations: - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -## Step-by-Step Tutorial +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -# Products +### Token Transfer with Message -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -## Transfer Products +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +### Governance -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -
+#### Action Structure -::spantable:: +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -::end-spantable:: +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -
+```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +#### Actions -## Bridging UI +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -## Real-time Data +## Lifetime of a Message -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -## Multichain Governance +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -# Wormhole Use Cases +## Next Steps -
-
+
-## Cross-Chain Swaps and Liquidity Aggregation +- :octicons-book-16:{ .lg .middle } **Guardians** -Enable seamless swaps between chains with real-time liquidity routing. + --- -
-
+ Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -🛠 **Wormhole products used:** + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + --- -
-
+ Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -
-
+
+--- END CONTENT --- -## Borrowing and Lending Across Chains +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -Let users borrow assets on one chain using collateral from another. +# Introduction to Wormhole -
-
+In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -🛠 **Wormhole products used:** +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -
-
+!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
-
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -## Real-Time Price Feeds and Trading Strategies +## What Problems Does Wormhole Solve? -Fetch price feeds across multiple chains for DeFi applications. +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -
-
+Critical problems Wormhole addresses include: -🛠 **Wormhole products used:** +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +## What Does Wormhole Offer? -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -
-
+- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. +## What Isn't Wormhole? -
-
+- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -## Asset Movement Between Bitcoin and Other Chains +## Use Cases of Wormhole -Enable direct BTC transfers without wrapped assets. +Consider the following examples of potential applications enabled by Wormhole: -
-
+- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -🛠 **Wormhole products used:** +## Explore -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Discover more about the Wormhole ecosystem, components, and protocols: -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -
-
+Demos offer more realistic implementations than tutorials: -## Decentralized Social Platforms +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -Enable seamless communication and asset transfer across decentralized social networks. + -🛠 **Wormhole products used:** +!!! note + Wormhole Integration Complete? -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -
-
+## Supported Networks by Product +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -## Memecoin Launchpads +# Security -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -🛠 **Wormhole products used:** +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +In summary: -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -
-
+Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -## Cross-Chain Perpetuals +### Governance -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -🛠 **Wormhole products used:** +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +Via governance, the Guardians can: -
-
+- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -## Gas Abstraction +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: -🛠 **Wormhole products used:** +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +## Asset Layer Protections -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -
-
+## Open Source -## Bridging Intent Library +Wormhole builds in the open and is always open source. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -
-
+## Audits -🛠 **Wormhole products used:** +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -
-
+## Bug Bounties +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -
-
+Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -## Multichain Prediction Markets +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -
-
+## Learn More -🛠 **Wormhole products used:** +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +# Get Started with the Solidity SDK -
-
+The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. +## Install the SDK -
-
+Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -## Cross-Chain Payment Widgets +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +## Key Components -
-
+The following key components and features work together to make your on-chain Wormhole integration easier to build. -🛠 **Wormhole products used:** +??? interface "Base contracts" -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers + Leverage base contracts to send and receive messages and tokens. -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -
-
+??? interface "Interfaces" + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -
-
+ - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -## Oracle Networks +??? interface "Constants" -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -
-
+ - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -🛠 **Wormhole products used:** +## Example Usage -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +### Prerequisites +Before you begin, ensure you have the following: -
-
+- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer +### Set Up a Project -
-
+Follow these steps to prepare your development environment: -## Cross-Chain Staking +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -Enable users to stake assets on one chain while earning rewards or securing networks on another. + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -
-
+2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -🛠 **Wormhole products used:** + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -
-
---- END CONTENT --- + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -## Reference Concepts [shared: true] + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` ---- + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -## List of shared concept pages: +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. +## Use Contracts to Transfer USDC -## Full content for shared concepts: +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- + ```bash + touch script/transfer.ts + ``` -# Reference +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -## Get Started +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -
+ // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - --- + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); - --- + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -2838,7 +3119,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -2893,7 +3174,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -3109,262 +3390,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -3376,7 +3491,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -3551,7 +3666,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -3632,4 +3747,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-solidity-sdk.txt b/llms-files/llms-solidity-sdk.txt index 693f11660..cbb48642b 100644 --- a/llms-files/llms-solidity-sdk.txt +++ b/llms-files/llms-solidity-sdk.txt @@ -13,114 +13,15 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/cli.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/dev-env.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/solidity-sdk.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/cli/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/dev-env.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/sdk-reference.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/toolkit/ ---- BEGIN CONTENT --- ---- -title: Wormhole Tooling -description: This page lists key dev tools, including the WormholeScan Explorer, Wormhole CLI, Wormhole SDKs, and APIs for querying network data. -categories: Solidity-SDK ---- - -# Wormhole Tooling - -Regardless of which network development environment you are using, there are a few Wormhole-specific tools you should know about. - -## Get Started - -
- -- :octicons-telescope-16:{ .lg .middle } **Wormholescan** - - --- - - Wormholescan is an explorer for looking at individual transfer statuses on Mainnet and Testnet. - - [:custom-arrow: Review transactions on Wormholescan](https://wormholescan.io){target=\_blank} - -- :octicons-plug-16:{ .lg .middle } **Wormholescan API** - - --- - - Leverage the Wormholescan API to programmatically access Wormhole network data, including transaction details and VAAs. - - [:custom-arrow: Explore the Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} - -- :octicons-code-square-16:{ .lg .middle } **Wormhole CLI Tool** - - --- - - The Wormhole CLI is a Swiss-Army knife utility command line tool. It is excellent for creating one-off VAAs, parsing VAAs, reading Wormhole contract configurations, and more. - - [:custom-arrow: Get started with the CLI](/docs/build/toolkit/cli/) - -- :octicons-code-square-16:{ .lg .middle } **Wormhole SDK** - - --- - - Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC transfers. - - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/typescript-sdk/) - -- :octicons-code-square-16:{ .lg .middle } **Solidity SDK** - - --- - - Learn about Wormhole's Solidity SDK, including key components, interfaces, and tools for developing cross-chain decentralized applications on EVM-compatible blockchains. - - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/solidity-sdk/) - -- :octicons-beaker-16:{ .lg .middle } **Tilt** - - --- - - Learn about Tilt, a Wormhole developer environment with a local Kubernetes set up for cross-chain testing with Guardian nodes and relayers for seamless development. - - [:custom-arrow: Get started with Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} - - - -
- -## Additional Resources - -
- -- :octicons-code-square-16:{ .lg .middle } **Wormhole Spy SDK** - - --- - - The Wormhole Spy SDK allows you to listen to all the Guardian Network activity. - - [:custom-arrow: Check out the Spy SDK repository](https://github.com/wormhole-foundation/wormhole/tree/main/spydk/js){target=\_blank} - -- :octicons-pencil-16:{ .lg .middle } **VAA Parser** - - --- - - The VAA Parser is a resource for parsing out details of an encoded VAA. - - [:custom-arrow: Try the VAA Parser](https://wormholescan.io/#/developers/vaa-parser){target=\_blank} - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/toolkit/cli/ +Doc-Content: https://wormhole.com/docs/tools/cli/get-started/ --- BEGIN CONTENT --- --- title: Wormhole CLI @@ -179,7 +80,7 @@ Options: ### Subcommands -??? code "Aptos" +??? interface "Aptos" ```bash worm aptos INSERT_COMMAND @@ -209,7 +110,7 @@ Options: --version Show version number [boolean]
``` -??? code "Edit VAA" +??? interface "Edit VAA" ```bash worm edit-vaa INSERT_COMMAND @@ -238,7 +139,7 @@ Options: --guardian-secret, --gs Guardian's secret key [string] ``` -??? code "EVM" +??? interface "EVM" ```bash worm evm INSERT_COMMAND @@ -261,7 +162,7 @@ Options: --rpc RPC endpoint [string] ``` -??? code "Generate" +??? interface "Generate" ```bash worm generate INSERT_COMMAND @@ -279,7 +180,7 @@ Options: -g, --guardian-secret Guardians' secret keys (CSV) [string] [required] ``` -??? code "Info" +??? interface "Info" ```bash worm info INSERT_COMMAND @@ -307,7 +208,7 @@ Options: --version Show version number [boolean]
``` -??? code "NEAR" +??? interface "NEAR" ```bash worm near INSERT_COMMAND @@ -329,7 +230,7 @@ Options: -r, --rpc Override default rpc endpoint url [string] ``` -??? code "Parse" +??? interface "Parse" ```bash worm parse INSERT_VAA @@ -341,7 +242,7 @@ Options: --version Show version number [boolean] ``` -??? code "Recover" +??? interface "Recover" ```bash worm recover INSERT_DIGEST INSERT_SIGNATURE @@ -354,7 +255,7 @@ Options: --version Show version number [boolean] ``` -??? code "Status" +??? interface "Status" ```bash worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH @@ -427,7 +328,7 @@ Options: --version Show version number [boolean] ``` -??? code "Submit" +??? interface "Submit" ```bash worm submit INSERT_VAA @@ -506,7 +407,7 @@ Options: [boolean] [default: false] ``` -??? code "Sui" +??? interface "Sui" ```bash worm sui INSERT_COMMAND @@ -535,7 +436,7 @@ Options: --version Show version number [boolean] ``` -??? code "Transfer" +??? interface "Transfer" ```bash worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK @@ -660,7 +561,7 @@ Options: --rpc RPC endpoint [string] ``` -??? code "Verify VAA" +??? interface "Verify VAA" ```bash worm verify-vaa INSERT_VAA, INSERT_NETWORK @@ -671,10 +572,9 @@ Options: -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] ``` - ## Examples -### VAA generation +### Generate a VAA Use `generate` to create VAAs for testing. For example, use the following command to create an NFT bridge registration VAA: @@ -698,7 +598,7 @@ worm generate attestation --emitter-chain ethereum \ --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 ``` -### VAA parsing +### Parse a VAA Use `parse` to parse a VAA into JSON: @@ -746,7 +646,7 @@ payload: { } ``` -### Submitting VAAs +### Submit VAAs Use `submit` to submit a VAA to a chain. It first parses the VAA and determines the destination chain and module. For example, a contract upgrade contains both the target chain and module, so the only required argument is the network moniker (`mainnet` or `testnet`): @@ -775,7 +675,7 @@ worm submit $(cat guardian-upgrade.txt) --network mainnet --chain celo The VAA payload type (Guardian set upgrade) specifies that this VAA should go to the core bridge, and the tool directs it there. -### Getting Info +### Fetch Contract Information To get info about a contract (only EVM supported at this time), use the following command: @@ -858,8 +758,6 @@ Running this command generates the following output: } ``` -### Additional Info Examples - You can get the contract address for a module as follows: ```bash @@ -872,6 +770,8 @@ To get the contract address for `NFTBridge` on BSC Mainnet, for example, you can worm info contract mainnet bsc NFTBridge ``` +### Fetch Chain Information + You can get the RPC address for a chain as follows: ```bash @@ -885,7 +785,7 @@ worm info rpc mainnet bsc ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/dev-env/ +Doc-Content: https://wormhole.com/docs/tools/dev-env/ --- BEGIN CONTENT --- --- title: Local Dev Environment @@ -899,7 +799,7 @@ Developers building for smart contract integration will want to set up a develop ## Tooling Installation -The [Wormhole CLI Tool](/docs/build/toolkit/cli/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/build/start-building/supported-networks/){target=\_blank}. +The [Wormhole CLI Tool](/docs/tools/cli/get-started/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/products/reference/supported-networks/){target=\_blank}. ## Development Stages @@ -917,7 +817,7 @@ Relying on native tools when possible allows for more rapid prototyping and iter ### Integration -For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/build/start-building/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. +For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/products/reference/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. !!! note Variation in host environments causes unique issues, and the computational intensity of multiple simultaneous local validators can make setting them up difficult or time-consuming. You may prefer Testnets for the simplest integration testing. @@ -935,7 +835,7 @@ If you'd like to set up a local validator environment, follow the setup guide fo ### Testnet -When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: +When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: ```text https://api.testnet.wormholescan.io @@ -943,14 +843,14 @@ https://api.testnet.wormholescan.io ### Mainnet -The Mainnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: +The Mainnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: ```text https://api.wormholescan.io ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/faqs/ +Doc-Content: https://wormhole.com/docs/tools/faqs/ --- BEGIN CONTENT --- --- title: Toolkit FAQs @@ -1000,14 +900,407 @@ To manually submit a VAA (Verifiable Action Approval) to a destination chain, fo 3. **Submit the VAA through Etherscan (for EVM chains)** - once the VAA is in hex format, go to the [Etherscan UI](https://etherscan.io/){target=\_blank} and submit it through the [`TokenBridge`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} contract’s method (such as the `CompleteTransfer` function or `CompleteTransferWithPayload`) - - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/build/reference/contract-addresses/){target=\_blank} section + - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/products/reference/contract-addresses/){target=\_blank} section - Interact with the smart contract through the Etherscan UI by pasting the hex-encoded VAA into the appropriate field Following these steps, you can manually submit a VAA in the proper format to a destination chain. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/solidity-sdk/ +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- + +# Get Started with the Solidity SDK + +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. + +## Install the SDK + +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: + +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` + +## Key Components + +The following key components and features work together to make your on-chain Wormhole integration easier to build. + +??? interface "Base contracts" + + Leverage base contracts to send and receive messages and tokens. + + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. + +??? interface "Interfaces" + + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. + + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. + +??? interface "Constants" + + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. + + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. + +## Example Usage + +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. + +### Prerequisites +Before you begin, ensure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer + +### Set Up a Project + +Follow these steps to prepare your development environment: + +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: + + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` + +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: + + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` + +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } + + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` + + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` + + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. + +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. + +## Use Contracts to Transfer USDC + +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: + + ```bash + touch script/transfer.ts + ``` + +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); + +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } + + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } + + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); + + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; + + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); + + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); + + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); + + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); + + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` + + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. + +3. Run the script using the following command: + + ```bash + npx tsx script/transfer.ts + ``` + +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
+ +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. + +## Next Steps + +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/sdk-reference/ --- BEGIN CONTENT --- --- title: Solidity SDK @@ -1017,42 +1310,32 @@ categories: Solidity-SDK # Solidity SDK -## Introduction - -The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} simplifies cross-chain messaging on EVM-compatible chains by providing essential Solidity interfaces, utility libraries, and testing tools. It allows developers to build secure and efficient cross-chain decentralized applications (dApps) without manually interacting with Wormhole’s core contracts across multiple chains. +This page covers all you need to know about the functionality offered through the Wormhole Solidity SDK. -By abstracting away complex interactions, the SDK drastically reduces the overhead associated with cross-chain development. It provides: +
- - **Unified interfaces** - developers can use a standardized set of Solidity interfaces to handle cross-chain messaging, token transfers, and verifiable action approvals (VAAs) without needing to manage the underlying infrastructure - - **Automated message delivery** - the SDK leverages Wormhole’s relayer infrastructure, automatically delivering messages across chains, reducing the need for manual intervention, and simplifying gas management on the target chain - - **Seamless integration with Wormhole services** - the SDK integrates with Wormhole’s `TokenBridge` and Circle’s CCTP, providing built-in mechanisms for cross-chain asset transfers, making token bridges and cross-chain messaging easy to implement - - **Testing and development tools** - it comes with comprehensive tools for local testing and simulation, allowing developers to validate their cross-chain logic before deployment, minimizing the risk of errors in production environments +- :octicons-download-16:{ .lg .middle } **Installation** -These features significantly streamline the development workflow by reducing complexity and offering tools compatible with various EVM versions. This helps developers avoid issues that arise from differences in EVM equivalence across chains. + --- -This guide covers installation, key concepts, and usage examples to help you build secure cross-chain applications using the SDK, from token transfers to advanced message passing. + Find installation instructions using Foundry and Forge to pull the necessary libraries into your project. -## Installation + [:custom-arrow: Install the SDK](/docs/tools/solidity-sdk/get-started/#installation) -To install the SDK, use [Foundry and Forge](https://book.getfoundry.sh/getting-started/installation){target=\_blank}. This pulls the necessary libraries into your project: +- :octicons-download-16:{ .lg .middle } **Source Code** -```bash -forge install wormhole-foundation/wormhole-solidity-sdk@v0.1.0 -``` + --- -When developing cross-chain applications, ensure that the chains you target support the EVM version you’re using. For instance, the PUSH0 opcode (introduced in Solidity 0.8.20) may not be available on all chains. To avoid compatibility issues, you can set the EVM version in your `foundry.toml` file: + Want to go straight to the source? Check out the Solidity SDK GitHub repository. -```toml -evm_version = "paris" -``` + [:custom-arrow: View GitHub Repository](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} -This ensures compatibility across all targeted chains, even if some do not yet support the latest EVM upgrades. +
## Key Considerations Before deploying applications using the Wormhole Solidity SDK, keep these considerations in mind: - - **Version compatibility** - the SDK is evolving, and using tagged releases for production is crucial, as the main branch may introduce breaking changes - **IERC-20 remapping** - the SDK provides a remapping mechanism to handle potential conflicts between different implementations of IERC20, ensuring seamless integration with other libraries - **Testing** - given the cross-chain dependencies, testing all integrations is critical to avoid issues in production environments @@ -1064,7 +1347,7 @@ The Wormhole Solidity SDK consists of key components that streamline cross-chain The [`WormholeRelayerSDK.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank} contract simplifies cross-chain messaging and asset transfers by integrating several necessary modules, including the Wormhole relayer. By automating message delivery between chains, the Wormhole relayer removes the need for developers to manage relayer infrastructure or handle gas on the target chain. Delivery providers handle the message payload, ensuring secure and efficient communication. -You can refer to the [Wormhole relayer documentation](/docs/build/core-messaging/wormhole-relayers/){target=\_blank} for more details. +You can refer to the [Wormhole relayer documentation](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank} for more details. Key modules in the SDK include: @@ -1188,9 +1471,9 @@ abstract contract Base { ### Interface for Cross-Chain Messages -The Wormhole Solidity SDK interacts with the Wormhole relayer for sending and receiving messages across EVM-compatible chains. The [`IWormholeRelayer`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeRelayer.sol){target=\_blank} and [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interfaces are central to cross-chain communication, enabling secure and efficient message delivery. +The Wormhole Solidity SDK interacts with the Wormhole relayer for sending and receiving messages across EVM-compatible chains. The [`IWormholeRelayer`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeRelayer.sol){target=\_blank} includes several interfaces that are central to cross-chain communication, enabling secure and efficient message delivery. -For detailed information on how to implement these interfaces, refer to the [Wormhole Relayer Interfaces documentation](/docs/build/core-messaging/wormhole-relayers/#wormhole-relayer-interfaces){target=\_blank}. This section covers: +For detailed information on how to implement these interfaces, refer to the [Wormhole Relayer Interfaces documentation](/docs/products/messaging/guides/wormhole-relayers/#wormhole-relayer-interfaces){target=\_blank}. This section covers: - **`IWormholeRelayer`** – methods for sending cross-chain messages, VAAs, and token transfers - **`IWormholeReceiver`** – the required implementation for receiving cross-chain messages @@ -1309,7 +1592,7 @@ contract CrossChainTokenReceiver is TokenReceiver { In this example, `TokenReceiver` allows the contract to handle tokens sent from the source chain. Once the cross-chain message is received, the `receiveWormholeMessages` function processes the incoming tokens. Always validate the message's authenticity and source. !!! note - Always verify the source of incoming messages and tokens to prevent unauthorized access to your contract. Please refer to the [Emitter Verification](/docs/build/core-messaging/core-contracts/#validating-the-emitter/){target=\_blank} section for more details. + Always verify the source of incoming messages and tokens to prevent unauthorized access to your contract. Please refer to the [Emitter Verification](/docs/products/messaging/guides/core-contracts/#validating-the-emitter/){target=\_blank} section for more details. ## Testing Environment @@ -1317,8 +1600,8 @@ The SDK includes built-in support for Forge-based testing, which allows you to t For a detailed example, check out the below repositories: - - [Cross chain messaging](/docs/tutorials/solidity-sdk/cross-chain-contracts/){target=\_blank} - - [Cross chain token transfer](/docs/tutorials/solidity-sdk/cross-chain-token-contracts/){target=\_blank} + - [Cross chain messaging](/docs/products/messaging/tutorials/cross-chain-contracts/){target=\_blank} + - [Cross chain token transfer](/docs/products/messaging/tutorials/cross-chain-token-contracts/){target=\_blank} --- END CONTENT --- ## Basics Concepts [shared: true] @@ -1335,2013 +1618,2469 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary +# Get Started with Messaging -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Chain ID +## Prerequisites -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +Before you begin, ensure you have the following: -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -## Consistency Level +## Configure Your Messaging Environment -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a directory and initialize a Node.js project: -## Delivery Provider + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Emitter + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Finality + ```bash + npx tsc --init + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -## Guardian +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. + ```bash + npm install @wormhole-foundation/sdk + ``` -## Guardian Network +5. Create a new file named `main.ts`: -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. + ```bash + touch main.ts + ``` -## Guardian Set +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -## Heartbeat + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; -## Observation + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -## Relayer + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -A relayer is any process that delivers VAAs to a destination. + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -## Sequence + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -## Spy + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -## VAA + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +2. Run the script using the following command: -## Validator + ```bash + npx tsx main.ts + ``` -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
+ +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages + +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. + +## Next Steps + +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts categories: Basics --- -# Infrastructure Components +# Get Started with Core Contracts -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +## Introduction -## Get Started +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -Start here for an overview of Wormhole architecture components and security mechanisms: +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -
+This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Prerequisites - --- +To interact with the Wormhole Core Contract, you'll need the following: - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +## How to Interact with Core Contracts -- :octicons-book-16:{ .lg .middle } **Security** +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - --- +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. - [:custom-arrow: Learn About Security](/docs/learn/security/) +### Sending Messages -
+To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -## Explore Components +=== "EVM" -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. + ??? interface "Parameters" -## Next Steps + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -
+ --- -- :octicons-book-16:{ .lg .middle } **Messaging Components** + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. - --- + --- - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + ??? interface "Returns" -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" - --- + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +// Check fee and send parameters -
---- END CONTENT --- +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -# Architecture +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -## Overview + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +=== "Solana" -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + ??? interface "Parameters" - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -## On-Chain Components + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -## Off-Chain Components + ??? child "Type `PostMessage<'info>`" -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -## Next Steps + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -
+ --- -- :octicons-book-16:{ .lg .middle } **Core Contracts** + `batch_id` ++"u32"++ + + An identifier for the message batch. - --- + --- - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + --- -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" - --- + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -
---- END CONTENT --- +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -# Core Contracts + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -## Introduction +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. +### Receiving Messages -## Key Functions +The way a message is received and handled depends on the environment. -Key functions of the Wormhole Core Contract include the following: +=== "EVM" -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -## How the Core Contract Works + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. + ??? interface "Parameters" -The following describes the role of the Wormhole Core Contract in message transfers: + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions + ??? interface "Returns" -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -### Message Submission - -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: - -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + ??? child "Struct `VM`" -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -### Message Reception + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -## Multicast + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + ??? interface "Example" -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + // Perform safety checks here -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); -## Next Steps + // Your custom application logic here +} + ``` -
+ View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** +=== "Solana" - --- + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + Retrieve the raw message data: - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + ??? interface "Example" - --- + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -
---- END CONTENT --- +#### Validating the Emitter -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -## Guardian +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -Guardians fulfill their role in the messaging protocol as follows: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +await tx.wait(); +``` -## Guardian Network +#### Additional Checks -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -The Guardian Network is designed to help Wormhole deliver on five key principles: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -The following sections explore each principle in detail. +## Source Code References -### Decentralization +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -Two common approaches to decentralization have notable limitations: +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +# Wormhole Relayer -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +## Introduction -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -To answer that, consider these key constraints and design decisions: +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +## Get Started with the Wormhole Relayer -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -### Modularity +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-### Chain Agnosticism +### Wormhole Relayer Interfaces -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -### Scalability +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +## Interact with the Wormhole Relayer -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -### Upgradeable +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -Wormhole is designed to adapt and evolve in the following ways: +Your initial set up should resemble the following: -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -## Next Steps +contract Example { + IWormholeRelayer public wormholeRelayer; -
+ constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -- :octicons-book-16:{ .lg .middle } **Relayers** +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. - --- +### Send a Message - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. - --- +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -
---- END CONTENT --- +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -# Relayers - -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. - -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. - -There are three primary types of relayers discussed: - -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved - -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +### Receive a Message -## Fundamentals +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Key characteristics of VAAs include: +## Delivery Guarantees -- Public emission from the Guardian Network +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- Authentication through signatures from the Guardian Network +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- Verifiability by any entity or any Wormhole Core Contract +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +## Delivery Statuses -Keep in mind the following security considerations around relayers: +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -## Client-Side Relaying +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -### Key Features +## Other Considerations -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -### Implementation +## Track the Progress of Messages with the Wormhole CLI -Users themselves carry out the three steps of the cross-chain process: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -1. Perform an action on chain A +=== "Mainnet" -2. Retrieve the resulting VAA from the Guardian Network + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -3. Perform an action on chain B using the VAA +=== "Testnet" -### Considerations + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -- Users must sign all required transactions with their own wallet +## Step-by-Step Tutorial -- Users must have funds to pay the transaction fees on every chain involved +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -- The user experience may be cumbersome due to the manual steps involved +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -## Custom Relayers +# Messaging Overview -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +## Key Features -### Key Features +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## How It Works -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +The messaging flow consists of several core components: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -### Implementation +## Use Cases -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Considerations +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- Development work and hosting of relayers are required +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +- **Gas Abstraction** -## Wormhole Relayers + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +- **Bridging Intent Library** -### Key Features + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -### Implementation +## Next Steps -The Wormhole relayer integration involves two key steps: +Follow these steps to work with Wormhole Messaging: -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Considerations +# Products -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- All computations are performed on-chain +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -- Potentially less gas-efficient compared to custom relayers +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +## Transfer Products -- Support may not be available for all chains +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -## Next Steps +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-- :octicons-book-16:{ .lg .middle } **Spy** +::spantable:: - --- +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +::end-spantable:: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +
-- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - --- +
- Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +## Bridging UI -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - --- +## Real-time Data - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Multichain Governance -
+[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Spy +# Glossary -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Chain ID -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -## Key Features +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +## Consistency Level -## Integrator Use Case +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +## Delivery Provider -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -## Observable Message Categories +## Emitter -A Spy can access the following categories of messages shared over the gossip protocol: +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +## Finality - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +## Guardian - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +## Guardian Network - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -## Additional Resources +## Guardian Set -
+The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +## Heartbeat - --- +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +## Observation -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. - --- +## Relayer - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +A relayer is any process that delivers VAAs to a destination. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +## Sequence -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - --- +## Spy - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +## VAA -
+[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. -## Next Steps +## Validator -
+A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- -- :octicons-code-16:{ .lg .middle } **Run a Spy** +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- - --- - - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). - - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} - -- :octicons-code-16:{ .lg .middle } **Use Queries** - - --- - - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. - - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ ---- BEGIN CONTENT --- ---- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. -categories: Basics ---- - -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Architecture -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Overview -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -## VAA Format +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -The basic VAA consists of header and body components described as follows: +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - Where each `signature` is: + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## On-Chain Components -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +## Off-Chain Components -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Consistency and Finality +## Next Steps -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +
-Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- :octicons-book-16:{ .lg .middle } **Core Contracts** -## Signatures + --- -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -## Payload Types + --- -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -### Token Transfer + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +
+--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# The Wormhole Ecosystem -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Ecosystem Overview -### Attestation +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -The message format for token attestation is as follows: +## Bringing It All Together: Interoperability in Action -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. -#### Attestation Tips +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -Be aware of the following considerations when working with attestations: +## Next Steps -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +# Core Contracts -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Introduction -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer with Message +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +## Key Functions -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Key functions of the Wormhole Core Contract include the following: -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## How the Core Contract Works -### Governance +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +The following describes the role of the Wormhole Core Contract in message transfers: -#### Action Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Message Submission -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -#### Actions +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +### Message Reception -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Lifetime of a Message +## Multicast -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Introduction to Wormhole - -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +## Guardian -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +Guardians fulfill their role in the messaging protocol as follows: -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +## Guardian Network -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## What Problems Does Wormhole Solve? +The Guardian Network is designed to help Wormhole deliver on five key principles: -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -Critical problems Wormhole addresses include: +The following sections explore each principle in detail. -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +### Decentralization -## What Does Wormhole Offer? +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +Two common approaches to decentralization have notable limitations: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -## What Isn't Wormhole? +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -## Use Cases of Wormhole +To answer that, consider these key constraints and design decisions: -Consider the following examples of potential applications enabled by Wormhole: +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -## Explore +### Modularity -Discover more about the Wormhole ecosystem, components, and protocols: +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +### Chain Agnosticism -## Demos +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -Demos offer more realistic implementations than tutorials: +### Scalability -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. - +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -!!! note - Wormhole Integration Complete? +### Upgradeable - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +Wormhole is designed to adapt and evolve in the following ways: - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model + +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + +## Next Steps + +
-## Supported Blockchains +- :octicons-book-16:{ .lg .middle } **Relayers** + + --- + + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. + + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) + +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -Wormhole supports a growing number of blockchains. + --- + + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Security +# Relayers -## Core Security Assumptions +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +There are three primary types of relayers discussed: -In summary: +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -## Guardian Network +## Fundamentals -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -### Governance +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +Key characteristics of VAAs include: -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +- Public emission from the Guardian Network -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +- Authentication through signatures from the Guardian Network -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- Verifiability by any entity or any Wormhole Core Contract -Via governance, the Guardians can: +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +Keep in mind the following security considerations around relayers: -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## Monitoring +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +## Client-Side Relaying -Guardians monitor: +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Key Features -## Asset Layer Protections +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +### Implementation -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Users themselves carry out the three steps of the cross-chain process: -## Open Source +1. Perform an action on chain A -Wormhole builds in the open and is always open source. +2. Retrieve the resulting VAA from the Guardian Network -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +3. Perform an action on chain B using the VAA -## Audits +### Considerations -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +- Users must sign all required transactions with their own wallet -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +- Users must have funds to pay the transaction fees on every chain involved -## Bug Bounties +- The user experience may be cumbersome due to the manual steps involved -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +## Custom Relayers -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +### Key Features -## Learn More +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics ---- +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application -# Get Started with Core Contracts +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience -## Introduction +### Implementation -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +### Considerations -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." -## Prerequisites +- Development work and hosting of relayers are required -To interact with the Wormhole Core Contract, you'll need the following: +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +- Relayers are responsible for availability, and adding dependencies for the cross-chain application -## How to Interact with Core Contracts +## Wormhole Relayers -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +### Key Features -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -### Sending Messages +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +### Implementation -=== "EVM" +The Wormhole relayer integration involves two key steps: - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ??? interface "Parameters" +### Considerations - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - --- +- All computations are performed on-chain - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +- Potentially less gas-efficient compared to custom relayers - --- +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- Support may not be available for all chains - ??? interface "Returns" +## Next Steps - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +
- ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +- :octicons-book-16:{ .lg .middle } **Spy** -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); + --- -// Check fee and send parameters + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` + --- - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -=== "Solana" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` + --- - ??? interface "Parameters" + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +
+--- END CONTENT --- - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +# Spy - ??? child "Type `PostMessage<'info>`" +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - --- +## Key Features - `batch_id` ++"u32"++ - - An identifier for the message batch. +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - --- +## Integrator Use Case - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - --- +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +## Observable Message Categories - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +A Spy can access the following categories of messages shared over the gossip protocol: - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +## Additional Resources -### Receiving Messages +
-The way a message is received and handled depends on the environment. +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -=== "EVM" + --- - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} - ??? interface "Parameters" +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. + --- - ??? interface "Returns" + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) - ??? child "Struct `VM`" +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + --- - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided +
- ??? interface "Example" +## Next Steps - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +
- // Perform safety checks here +- :octicons-code-16:{ .lg .middle } **Run a Spy** - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); + --- - // Your custom application logic here -} - ``` + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -=== "Solana" +- :octicons-code-16:{ .lg .middle } **Use Queries** - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + --- - Retrieve the raw message data: + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) - ??? interface "Example" +
+--- END CONTENT --- - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +# Verified Action Approvals - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -#### Validating the Emitter +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +## VAA Format -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +The basic VAA consists of header and body components described as follows: -await tx.wait(); -``` +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -#### Additional Checks + Where each `signature` is: -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -## Source Code References +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- +## Consistency and Finality -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -# Wormhole Relayer +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -## Introduction +## Signatures -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -## Get Started with the Wormhole Relayer +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +## Payload Types -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+### Token Transfer -### Wormhole Relayer Interfaces +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +Transferring tokens from the sending chain to the destination chain requires the following steps: -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -## Interact with the Wormhole Relayer +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -Your initial set up should resemble the following: +### Attestation -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -contract Example { - IWormholeRelayer public wormholeRelayer; +The message format for token attestation is as follows: - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +#### Attestation Tips -### Send a Message +Be aware of the following considerations when working with attestations: -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +### Token Transfer with Message -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -### Receive a Message +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +### Governance -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +#### Action Structure -## Delivery Guarantees +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Delivery Statuses +#### Actions -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +## Lifetime of a Message -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -## Other Considerations +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +## Next Steps -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +
-## Track the Progress of Messages with the Wormhole CLI +- :octicons-book-16:{ .lg .middle } **Guardians** -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: + --- -=== "Mainnet" + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -=== "Testnet" +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` + --- -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -## Step-by-Step Tutorial + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/products/ +Doc-Content: https://wormhole.com/docs/protocol/introduction/ --- BEGIN CONTENT --- --- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics --- -# Products +# Introduction to Wormhole -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -## Transfer Products +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -::spantable:: +## What Problems Does Wormhole Solve? -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -::end-spantable:: +Critical problems Wormhole addresses include: -
+- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +## What Does Wormhole Offer? -## Bridging UI +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -## Real-time Data +## What Isn't Wormhole? -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -## Multichain Governance +## Use Cases of Wormhole -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +Consider the following examples of potential applications enabled by Wormhole: -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. + +## Explore + +Discover more about the Wormhole ecosystem, components, and protocols: -# Wormhole Use Cases +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -
-
+## Demos -## Cross-Chain Swaps and Liquidity Aggregation +Demos offer more realistic implementations than tutorials: -Enable seamless swaps between chains with real-time liquidity routing. +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -
-
+ -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +!!! note + Wormhole Integration Complete? -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +## Supported Networks by Product -
-
+Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -## Borrowing and Lending Across Chains +# Security -Let users borrow assets on one chain using collateral from another. +## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -🛠 **Wormhole products used:** +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +In summary: -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -
-
+Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -## Real-Time Price Feeds and Trading Strategies +### Governance -Fetch price feeds across multiple chains for DeFi applications. +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -🛠 **Wormhole products used:** +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Via governance, the Guardians can: -
-
+- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -## Asset Movement Between Bitcoin and Other Chains +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -Enable direct BTC transfers without wrapped assets. +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: -🛠 **Wormhole products used:** +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +## Asset Layer Protections -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -
-
+In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -## Decentralized Social Platforms +## Open Source -Enable seamless communication and asset transfer across decentralized social networks. +Wormhole builds in the open and is always open source. -
-
+- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -🛠 **Wormhole products used:** +## Audits -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -
-
+All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +## Bug Bounties -
-
+Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -## Memecoin Launchpads +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -
-
+For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -🛠 **Wormhole products used:** +## Learn More -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -
-
+## Install the SDK -## Cross-Chain Perpetuals +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -
-
+## Key Components -🛠 **Wormhole products used:** +The following key components and features work together to make your on-chain Wormhole integration easier to build. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +??? interface "Base contracts" -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. +??? interface "Interfaces" -
-
+ Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -## Gas Abstraction + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +??? interface "Constants" -
-
+ Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -🛠 **Wormhole products used:** + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +## Example Usage -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -
-
+### Set Up a Project -## Bridging Intent Library +Follow these steps to prepare your development environment: -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -
-
+ ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -🛠 **Wormhole products used:** +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +### Create and Deploy Contracts -
-
+This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. +Follow these steps to create and deploy your sender and receiver Solidity contracts: -
-
+1. Use the following example code to create `CrossChainSender.sol`: -## Multichain Prediction Markets + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -
-
+// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); -🛠 **Wormhole products used:** + cost = deliveryCost + wormhole.messageFee(); + } -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. -
-
+2. Use the following example code to create `CrossChainReceiver.sol`: + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; -
-
+import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -## Cross-Chain Payment Widgets +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -
-
+3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -🛠 **Wormhole products used:** +## Use Contracts to Transfer USDC -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + ```bash + touch script/transfer.ts + ``` -
-
+2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -
-
+ // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -## Oracle Networks + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -
-
+ // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); -🛠 **Wormhole products used:** + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); -
-
+ // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + process.exit(0); +})(); + ``` -
-
+ This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. -## Cross-Chain Staking +3. Run the script using the following command: -Enable users to stake assets on one chain while earning rewards or securing networks on another. + ```bash + npx tsx script/transfer.ts + ``` +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! +
-
- -🛠 **Wormhole products used:** -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +## Next Steps -
-
+- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. --- END CONTENT --- ## Reference Concepts [shared: true] @@ -3357,68 +4096,7 @@ While it may not be required for all use cases, it offers a deeper technical lay ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- - -# Reference - -## Get Started - -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. - -
- -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** - - --- - - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. - - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) - -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** - - --- - - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. - - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) - -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** - - --- - - Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. - - This includes the following protocol contracts: - - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP - - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) - -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** - - --- - - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. - - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -3541,7 +4219,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -3596,7 +4274,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -3812,262 +4490,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -4079,7 +4591,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -4254,7 +4766,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -4335,4 +4847,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-token-bridge.txt b/llms-files/llms-token-bridge.txt index d6c356199..f31be1974 100644 --- a/llms-files/llms-token-bridge.txt +++ b/llms-files/llms-token-bridge.txt @@ -13,2484 +13,3680 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/token-bridge.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/token-bridge.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/payload-structure.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/transfer-flow.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/guides/token-bridge-contracts.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/overview.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/transfers/token-bridge/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/concepts/payload-structure/ --- BEGIN CONTENT --- --- -title: Token Bridge -description: Learn about Wormhole's Token Bridge for cross-chain transfers using lock and mint mechanisms, ensuring secure and efficient asset movement. -categories: Token-Bridge, Transfer +title: Token Bridge Payload Structure +description: Discover the structure and purpose of each Token Bridge payload, including Transfer, TransferWithPayload, AssetMeta, and governance messages. +categories: Token-Bridge, Transfers --- -# Token Bridge - -Transferring tokens across blockchain networks is challenging due to the lack of interoperability. Maintaining token properties such as value, name, and precision while ensuring security during transfers often requires complex and costly solutions like liquidity pools or native swaps, which can introduce inefficiencies and risks. +# Message and Payload Structure -Wormhole’s Token Bridge addresses these challenges by providing a decentralized protocol for seamless cross-chain token transfers through a lock-and-mint mechanism. Using Wormhole’s message-passing protocol, the Token Bridge allows standards-compliant tokens, like ERC-20 on Ethereum or SPL on Solana, to be transferred between different blockchains while preserving their original attributes. +To enable secure and flexible cross-chain token transfers, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} defines a set of standardized payloads. These payloads are embedded in [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} and processed by bridge contracts on the source and destination chains. Each payload has a unique format and serves a specific role in the lifecycle of token bridging. -Offering a more efficient, scalable, and secure alternative to traditional solutions, the Token Bridge ensures that assets retain their properties across multiple blockchain ecosystems. Additionally, it supports flexible features like [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, enabling custom interactions by allowing tokens to carry additional data for smart contract integration on the destination chain. +This page outlines each payload type in detail. -This page introduces the core concepts and functions of Wormhole’s Token Bridge, explaining how it operates, its key features, and how it enables secure and efficient cross-chain token transfers. +## Transfer -### How Does It Work? +The `Transfer` payload (ID = `1`) is the core mechanism for moving tokens across chains. It is emitted when a user locks or burns tokens on the source chain. On the destination chain, it instructs the bridge to either mint a wrapped token or release native tokens from custody. -At the core of the Token Bridge lies the lock-and-mint mechanism, which uses the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} with a specific [payload](/docs/learn/infrastructure/vaas/#token-transfer){target=\_blank} to pass information about the transfer. Tokens on the source chain are locked, and wrapped tokens are minted on the destination chain. This approach guarantees that token transfers are secure and consistent, ensuring that token properties such as name, symbol, and decimal precision are preserved across chains. - -Before a token can be transferred to a new chain, the token’s metadata must be [attested](/docs/learn/infrastructure/vaas/#attestation){target=\_blank}. This process registers the token details (such as decimals and symbol) on the destination chain, enabling the creation of wrapped assets. +```text +PayloadID uint8 = 1 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +Fee uint256 +``` -While the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} has no specific receiver by default, transfers sent through the Token Bridge do have a specific receiver chain and address to ensure the tokens are minted to the expected recipient. +??? interface "Parameters" -In addition to standard token transfers, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}. This functionality allows users to attach additional data to token transfers, enabling more complex interactions with smart contracts on the destination chain. For instance, a token transfer can include a payload that triggers specific actions, such as interacting with a decentralized exchange (DEX) or automated market maker (AMM). + `PayloadID` ++"uint8"++ -### Token Transfer Flow + Value must be `1`, indicating a `Transfer` operation. -The transfer process is simple yet secure, involving a few key steps: + --- -1. **Attestation** - first, a token's metadata is attested on the source chain, ensuring that its properties are consistent across chains -2. **Locking** - on the source chain, the native token is locked in a custody account -3. **Message emission** - a message detailing the transfer is sent through Wormhole’s Guardian Network, which verifies the transfer and signs the message -4. **Verification and minting** - on the destination chain, the transfer message is verified, and wrapped tokens are minted, or native tokens are released from custody + `Amount` ++"uint256"++ -![Token Bridge detailed flow](/docs/images/learn/transfers/token-bridge/token-bridge-diagram.webp) + Amount being transferred, truncated to 8 decimals for consistency across all chains. -### Key Features of the Token Bridge + --- -The Token Bridge creates wrapped versions when tokens are transferred to a different chain. These wrapped assets represent the locked tokens on the source chain and allow users to interact with them on the destination chain. This mechanism ensures seamless functionality without needing liquidity pools or native token swaps. + `TokenAddress` ++"bytes32"++ -The Token Bridge employs a universal token representation that is compatible with various virtual machine (VM) data types. This allows the tokens to interact with decentralized applications (dApps) across different chains without issues related to differing token standards. + Address of the token. Left-zero-padded if shorter than 32 bytes + + --- -### Message and Payload Structure + `TokenChain` ++"uint16"++ -To facilitate cross-chain communication, the Token Bridge uses specialized payloads that carry the necessary information for token transfers and attestations. These payloads ensure that the correct tokens are minted or unlocked on the destination chain. + Chain ID of the token. + + --- -- `Transfer` - this payload initiates the transfer of tokens, either by minting wrapped tokens or releasing locked tokens -- `TransferWithPayload` - in addition to transferring tokens, this payload carries additional data, allowing integration with smart contracts or dApps on the target chain -- `AssetMeta` - before a token can be transferred for the first time, this payload is used to attest to the token’s metadata, including decimals, symbol, and name -- `RegisterChain` - register the Token Bridge contract (emitter address) for a foreign chain -- `UpgradeContract` - upgrade the contract + `To` ++"bytes32"++ -Each payload type is designed to serve a specific function in the token transfer process, ensuring that the bridge operates efficiently and securely. + Address of the recipient. Left-zero-padded if shorter than 32 bytes. + + --- -One of the key challenges in cross-chain token transfers is maintaining the correct token precision. The Token Bridge addresses this using the `AssetMeta` payload to store token metadata. Before transferring a token to a new chain, metadata such as its decimal precision, name, and symbol must be attested. The bridge ensures token amounts are truncated to a maximum of 8 decimals, guaranteeing compatibility with chains that may not support higher decimal precision. For example, an 18-decimal token on Ethereum will be represented with only eight decimals on the destination chain, simplifying integration with various decentralized applications. + `ToChain` ++"uint16"++ -### Security and Authorization + Chain ID of the recipient. + + --- -The Token Bridge uses an emitter chain and address authorization system to verify the validity of messages. Each Token Bridge endpoint is registered on its respective chain, ensuring only trusted contracts can send or receive transfer messages. + `Fee` ++"uint256"++ -The [Wormhole Guardian Network](/docs/learn/infrastructure/guardians/#guardian-network){target=\_blank} plays a critical role in verifying each transfer and ensuring that the message is signed and relayed securely between chains. + Amount of tokens that the user is willing to pay as relayer fee. Must be less than Amount. Optional and can be claimed by relayers who submit the VAA on the target chain. + -### Portal Bridge +To keep `Transfer` messages small, they don't carry all the token's metadata. However, this means that before a token can be transferred to a new chain for the first time, the metadata needs to be bridged, and the wrapped asset needs to be created. Metadata, in this case, includes the number of decimals, which is a core requirement for instantiating a token. -A real-world example of Wormhole's Token Bridge in action is the [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides users with a simple interface to transfer tokens across multiple blockchains. Using the Wormhole infrastructure, Portal Bridge guarantees secure and seamless cross-chain transfers, making it easier for users to move assets between different blockchain ecosystems. ---- END CONTENT --- +## AssetMeta -Doc-Content: https://wormhole.com/docs/build/transfers/token-bridge/ ---- BEGIN CONTENT --- ---- -title: Get Started with Token Bridge -description: Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. -categories: Token-Bridge, Transfer ---- +Before a token can be transferred to a new chain for the first time, its metadata must be attested using the `AssetMeta` payload (ID = `2`). This ensures proper decimal precision and display. -# Token Bridge +```text +PayloadID uint8 = 2 +TokenAddress [32]uint8 +TokenChain uint16 +Decimals uint8 +Symbol [32]uint8 +Name [32]uint8 +``` -## Introduction +??? interface "Parameters" -Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. + `PayloadID` ++"uint8"++ -This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} page in the Learn section. + Value must be `2`, indicating a `AssetMeta` operation. -## Prerequisites + --- -To interact with the Wormhole Token Bridge, you'll need the following: + `TokenAddress` ++"[32]uint8"++ -- [The address of the Token Bridge contract](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers + Address of the token. Left-zero-padded if shorter than 32 bytes. -## How to Interact with Token Bridge Contracts + --- -The primary functions of the Token Bridge contracts revolve around: + `TokenChain` ++"uint16"++ -- **Attesting a token** - registering a new token for cross-chain transfers -- **Transferring tokens** - locking and minting tokens across chains -- **Transferring tokens with a payload** - including additional data with transfers + Chain ID of the token. -### Attest a Token + --- -Suppose a token has never been transferred to the target chain before transferring it cross-chain. In that case, its metadata must be registered so the Token Bridge can recognize it and create a wrapped version if necessary. + `Decimals` ++"uint8"++ -The attestation process doesn't require you to manually input token details like name, symbol, or decimals. Instead, the Token Bridge contract retrieves these values from the token contract itself when you call the `attestToken()` method. + Number of decimals the token uses on its native chain (not truncated to 8). -```solidity -function attestToken( - address tokenAddress, - uint32 nonce -) external payable returns (uint64 sequence); -``` + --- -??? interface "Parameters" + `Symbol` ++"[32]uint8"++ - `tokenAddress` ++"address"++ - - The contract address of the token to be attested. + Symbol of the token, UTF-8 encoded and padded to 32 bytes. --- - `nonce` ++"uint32"++ - - An arbitrary value provided by the caller to ensure uniqueness. - -??? interface "Returns" + `Name` ++"[32]uint8"++ - `sequence` ++"uint64"++ - - A unique identifier for the attestation transaction. + Name of the token, UTF-8 encoded and padded to 32 bytes. -??? interface "Example" +## TransferWithPayload - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); +The `TransferWithPayload` payload (ID = `3`) extends the standard token transfer by allowing developers to include arbitrary data. This enables interactions with destination chain smart contracts, such as triggering swaps or staking. -uint256 wormholeFee = wormhole.messageFee(); +```text +PayloadID uint8 = 3 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +FromAddress bytes32 +Payload bytes +``` -tokenBridge.attestToken{value: wormholeFee}( - address(tokenImpl), // the token contract to attest - 234 // nonce for the transfer -); - ``` +??? interface "Parameters" -When `attestToken()` is called, the contract emits a Verifiable Action Approval (VAA) containing the token's metadata, which the Guardians sign and publish. + `PayloadID` ++"uint8"++ -You must ensure the token is ERC-20 compliant. If it does not implement the standard functions, the attestation may fail or produce incomplete metadata. + Value must be `3`, indicating a `TransferWithPayload` operation. -### Transfer Tokens + --- -Once a token is attested, a cross-chain token transfer can be initiated following the lock-and-mint mechanism. On the source chain, tokens are locked (or burned if they're already a wrapped asset), and a VAA is emitted. On the destination chain, that VAA is used to mint or release the corresponding amount of wrapped tokens. + `Amount` ++"uint256"++ -Call `transferTokens()` to lock/burn tokens and produce a VAA with transfer details. + Amount being transferred, truncated to 8 decimals. -```solidity -function transferTokens( - address token, - uint256 amount, - uint16 recipientChain, - bytes32 recipient, - uint256 arbiterFee, - uint32 nonce -) external payable returns (uint64 sequence); -``` + --- -??? interface "Parameters" + `TokenAddress` ++"bytes32"++ - `token` ++"address"++ - - The address of the token being transferred. + Address of the token. Left-zero-padded if shorter than 32 bytes. --- - `amount` ++"uint256"++ - The amount of tokens to be transferred. + `TokenChain` ++"uint16"++ + + Chain ID of the token. --- - `recipientChain` ++"uint16"++ - The Wormhole chain ID of the destination chain. + `To` ++"bytes32"++ + + Address of the recipient. Must be a contract capable of parsing and handling the payload. Left-zero-padded if shorter than 32 bytes --- - `recipient` ++"bytes32"++ - The recipient's address on the destination chain. + `ToChain` ++"uint16"++ + + Chain ID of the recipient. --- - `arbiterFee` ++"uint256"++ - Optional fee to be paid to an arbiter for relaying the transfer. + `FromAddress` ++"bytes32"++ - --- + Address of the sender on the source chain. - `nonce` ++"uint32"++ - A unique identifier for the transaction. + --- -??? interface "Returns" + `Payload` ++"bytes"++ - `sequence` ++"uint64"++ - - A unique identifier for the transfer transaction. + Arbitrary data passed to the recipient contract. Can be used for DeFi operations, authentication, or app-specific logic. -??? interface "Example" - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); +Unlike `Transfer`, the `TransferWithPayload` message must be redeemed by the recipient contract since only that contract can handle the custom payload properly. -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +## RegisterChain -tokenBridge.transferTokens{value: wormholeFee}( - token, // address of the ERC-20 token to transfer - amount, // amount of tokens to transfer - recipientChain, // Wormhole chain ID of the destination chain - recipient, // recipient address on the destination chain (as bytes32) - arbiterFee, // fee for relayer - nonce // nonce for this transfer -); - ``` +The `RegisterChain` governance payload (Action ID = `1`) registers a Token Bridge emitter address for a foreign chain. This ensures the bridge only accepts messages from known peers. -Once a transfer VAA is obtained from the Wormhole Guardian network, the final step is to redeem the tokens on the destination chain. Redemption verifies the VAA's authenticity and releases (or mints) tokens to the specified recipient. To redeem the tokens, call `completeTransfer()`. +```text +Module [32]byte +Action uint8 = 1 +ChainId uint16 -```solidity -function completeTransfer(bytes memory encodedVm) external; +EmitterChainID uint16 +EmitterAddress [32]uint8 ``` ??? interface "Parameters" - `encodedVm` ++"bytes memory"++ - - The signed VAA containing the transfer details. + `Module` ++"[32]byte"++ -!!!note - - The Token Bridge normalizes token amounts to 8 decimals when passing them between chains. Make sure your application accounts for potential decimal truncation - - The VAA ensures the integrity of the message. Only after the Guardians sign the VAA can it be redeemed on the destination chain + Module identifier. Left-padded with `TokenBridge` for Token Bridge. -### Transfer Tokens with Payload + --- -While a standard token transfer moves tokens between chains, a transfer with a payload allows you to embed arbitrary data in the VAA. This data can be used on the destination chain to execute additional logic—such as automatically depositing tokens into a DeFi protocol, initiating a swap on a DEX, or interacting with a custom smart contract. + `Action` ++"uint8"++ -Call `transferTokensWithPayload()` instead of `transferTokens()` to include a custom payload (arbitrary bytes) with the token transfer. + Value must be `1`, indicating a `RegisterChain` operation. -```solidity -function transferTokensWithPayload( - address token, - uint256 amount, - uint16 recipientChain, - bytes32 recipient, - uint32 nonce, - bytes memory payload -) external payable returns (uint64 sequence); -``` + --- -??? interface "Parameters" + `ChainID` ++"uint16"++ - `token` ++"address"++ - - The address of the token being transferred. + The chain where this governance action should be applied. `0` is a valid value for all chains --- - `amount` ++"uint256"++ - The amount of tokens to be transferred. + `EmitterChainID` ++"uint16"++ + + Chain ID of the registered emitter. --- - `recipientChain` ++"uint16"++ - The Wormhole chain ID of the destination chain. + `EmitterAddress` ++"[32]uint8"++ - --- + Address of the registered emitter, left-zero-padded if shorter than 32 bytes. - `recipient` ++"bytes32"++ - The recipient's address on the destination chain. +This payload can only be emitted by the Wormhole governance contract, ensuring that each chain accepts messages only from one verified bridge emitter per remote chain. - --- +## UpgradeContract - `nonce` ++"uint32"++ - A unique identifier for the transaction. +The `UpgradeContract` governance payload (Action ID = `2`) facilitates upgrades to the Token Bridge contract on a specific chain. - --- +```text +Module [32]byte +Action uint8 = 2 +ChainId uint16 - `payload` ++"bytes memory"++ - Arbitrary data payload attached to the transaction. +NewContract [32]uint8 +``` -??? interface "Returns" - - `sequence` ++"uint64"++ - - A unique identifier for the transfer transaction. +??? interface "Parameters" -??? interface "Example" + `Module` ++"[32]byte"++ - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); + Module identifier, left-padded with `TokenBridge` for Token Bridge. -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); + --- -tokenBridge.transferTokensWithPayload{value: wormholeFee}( - token, // address of the ERC-20 token to transfer - amount, // amount of tokens to transfer - recipientChain, // Wormhole chain ID of the destination chain - recipient, // recipient address on the destination chain (as bytes32) - nonce, // nonce for this transfer - additionalPayload // additional payload data -); - ``` + `Action` ++"uint8"++ -After initiating a transfer on the source chain, the Wormhole Guardian network observes and signs the resulting message, creating a Verifiable Action Approval (VAA). You'll need to fetch this VAA and then call `completeTransferWithPayload()`. + Value must be `2`, indicating an `UpgradeContract` operation. -Only the designated recipient contract can redeem tokens. This ensures that the intended contract securely handles the attached payload. On successful redemption, the tokens are minted (if foreign) or released (if native) to the recipient address on the destination chain. For payload transfers, the designated contract can execute the payload's logic at this time. + --- -```solidity -function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory); -``` + `ChainID` ++"uint16"++ -??? interface "Parameters" + The target chain where the governance action should be applied. - `encodedVm` ++"bytes memory"++ + --- - The signed VAA containing the transfer details. + `NewContract` ++"[32]uint8"++ -??? interface "Returns" + Address of the new Token Bridge contract, left-zero-padded to 32 bytes. - `bytes memory` +This message allows the Wormhole governance system to deploy new versions of the bridge while retaining control over interoperability and security. - The extracted payload data. +## Summary of Payload Structure -## Source Code References +| Payload Type | ID | Purpose | Who Emits It | +|-----------------------|---------------|------------------------------------------------------------------------|------------------------| +| `Transfer` | PayloadID `1` | Moves tokens between chains by minting or releasing on the destination | Token Bridge contract | +| `AssetMeta` | PayloadID `2` | Attests token metadata (decimals, symbol, name) before first transfer | Token Bridge contract | +| `TransferWithPayload` | PayloadID `3` | Transfers tokens along with a custom payload for contract execution | Token Bridge contract | +| `RegisterChain` | Action `1` | Registers a verified Token Bridge emitter for a foreign chain | Wormhole governance | +| `UpgradeContract` | Action `2` | Upgrades the Token Bridge contract on a specific chain | Wormhole governance | +--- END CONTENT --- -For a deeper understanding of the Token Bridge implementation and to review the actual source code, please refer to the following links: +Doc-Content: https://wormhole.com/docs/products/token-bridge/concepts/transfer-flow/ +--- BEGIN CONTENT --- +--- +title: Flow of a Token Bridge Transfer +description: Learn how the Wormhole Token Bridge enables secure, cross-chain token transfers by combining token-specific logic with Wormhole's core message-passing layer. +categories: Token-Bridge, Transfer +--- -- [Token Bridge contract](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol){target=\_blank} -- [Token Bridge interface](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} +# Flow of a Transfer -## Portal Bridge +## Introduction -A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. +The [Wormhole Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} enables token transfers across blockchains by combining token-specific logic with [Wormhole's core messaging layer](/docs/protocol/architecture/){target=\_blank}. Each supported chain runs its own Token Bridge contract, which manages actions like locking, burning, minting, and releasing tokens. These contracts communicate directly with Wormhole's core message-passing layer to securely transmit messages between chains. -## FAQs +This guide provides a conceptual overview of the Token Bridge and its integration with the messaging layer. It outlines each step of the transfer flow and explains how different transfer types work in practice. -### Can ownership of wrapped tokens be transferred from the Token Bridge? +## Transfer Flow -No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. +Cross-chain token transfers using the Token Bridge follow these steps: - - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself - - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge +1. **Initiation on the Source Chain** + The transfer begins when a user calls the Token Bridge contract on the source chain: -The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. + - **Wrapped tokens**: The token is burned. + - **Original tokens**: If the token is native to the source chain, the token is locked in the contract. -Relevant contracts: +2. **Transfer Message Publication** + The Token Bridge contract invokes the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}, which emits an on-chain message event describing the transfer. - - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} - - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} - - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} +3. **Message Observation and Signing** + [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}—a decentralized network of validators—monitor the source chain for these message events. A supermajority (13 out of 19) signs the event to generate a [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}—a cryptographically signed attestation of the transfer. -### How do I update the metadata of a wrapped token? + The VAA is then published to the Wormhole network. -Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. +4. **VAA Submission to the Destination Chain** + The VAA must be submitted to the Token Bridge contract on the destination chain to complete the transfer. The Token Bridge contract then verifies the VAA by calling the Core Contract behind the scenes. This step can be handled in two ways: -### How do I calculate the current gas costs for Ethereum Mainnet VAA verification? + - **Automatic**: A relayer service detects the VAA and submits it to the Token Bridge contract. + - **Manual**: The user or dApp retrieves the VAA and submits it directly to the Token Bridge contract. -You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. +5. **Finalization of the Transfer on the Destination Chain** + After the VAA is verified on the destination chain, the Token Bridge contract completes the transfer: -### How can I update my wrapped token image on Solscan? + - **Wrapped tokens**: A wrapped representation of the original token is minted. + - **Original tokens**: If the token is native to the destination chain, the token is released to the recipient. -Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. +Consider this example: Alice wants to send 5 ETH from Ethereum to Solana. The ETH is locked on Ethereum’s Token Bridge, and an equivalent amount of wrapped ETH is minted on Solana. The diagram below illustrates this transfer flow. -To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. ---- END CONTENT --- +```mermaid +sequenceDiagram + participant Alice as Alice + participant TokenBridgeEth as Token Bridge Ethereum
(Source Chain) + participant CoreEth as Core Contract Ethereum
(Source Chain) + participant Guardians + participant TokenBridgeSol as Token Bridge Solana
(Destination Chain) + participant CoreSol as Core Contract Solana
(Destination Chain) -## Basics Concepts [shared: true] + Alice->>TokenBridgeEth: Initiate ETH transfer
(lock ETH) + TokenBridgeEth->>CoreEth: Publish transfer message + CoreEth-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA -The following section contains foundational documentation shared across all Wormhole products. -It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. -This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. -This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. + alt Automatic VAA submission + Guardians->>TokenBridgeSol: Relayer submits VAA + else Manual VAA submission + Alice->>Guardians: Retrieve VAA + Alice->>TokenBridgeSol: Submit VAA + end ---- + TokenBridgeSol->>CoreSol: Verify VAA + CoreSol-->>TokenBridgeSol: VAA verified + TokenBridgeSol-->>Alice: Mint wrapped ETH on Solana (complete transfer) +``` -## List of shared concept pages: +Maybe Alice wants to transfer her wrapped ETH on Solana back to native ETH on Ethereum. The wrapped ETH is burned on Solana’s Token Bridge, and the equivalent 5 ETH are released on Ethereum. The diagram below illustrates this transfer flow. + +```mermaid +sequenceDiagram + participant User as Alice + participant TokenBridgeSrc as Token Bridge Solana
(Source Chain) + participant CoreSrc as Core Contract Solana
(Source Chain) + participant Guardians + participant TokenBridgeDst as Token Bridge Ethereum
(Destination Chain) + participant CoreDst as Core Contract Ethereum
(Destination Chain) + + User->>TokenBridgeSrc: Initiate transfer
(burn wrapped ETH) + TokenBridgeSrc->>CoreSrc: Publish message + CoreSrc-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA + + alt Automatic VAA submission + Guardians->>TokenBridgeDst: Relayer submits VAA + else Manual VAA submission + User->>Guardians: Retrieve VAA + User->>TokenBridgeDst: User submits VAA directly + end + + TokenBridgeDst->>CoreDst: Verify VAA + CoreDst-->>TokenBridgeDst: VAA verified + TokenBridgeDst-->>User: Release native ETH on Ethereum (Complete transfer) +``` -## Full content for shared concepts: +## Automatic vs. Manual Transfers -Doc-Content: https://wormhole.com/docs/learn/glossary/ ---- BEGIN CONTENT --- ---- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics ---- +The Token Bridge supports two modes of transfer, depending on whether the VAA submission step is handled automatically or manually: -# Glossary +- **Automatic**: A relayer service listens for new VAAs and automatically submits them to the destination chain. +- **Manual**: The user (or dApp) must retrieve the VAA and manually submit it to the destination chain. -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Here's a quick breakdown of the key differences: -## Chain ID +| Feature | Automatic Transfer | Manual Transfer | +|---------------------------|-----------------------------|-------------------------------------| +| Who submits the VAA? | Relayer | User or dApp | +| User Experience | Seamless, one-step | Requires manual intervention | +| Best for | End-users, simple UIs | Custom dApps, advanced control | +| Dependency | Requires relayer support | None | -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +### Completing Manual Transfers -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +The user who initiated the transfer should complete the transfer within 24 hours for manual transfers. Guardian Sets are guaranteed to be valid for at least that long. If a user waits longer, the Guardian Set may have changed between initiation and redemption, causing the VAA to be rejected. -## Consistency Level +If this occurs, follow the [Replace Outdated Signatures in VAAs](){target=_blank} tutorial to update the VAA with signatures from the current Guardian Set. -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +## Token Bridge Relayer (TBR) -## Delivery Provider +When completing an automatic transfer using the Token Bridge—either through [Connect](/docs/products/connect/overview/){target=\_blank} or programmatically via the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}—the Token Bridge Relayer (TBR) manages the interaction with the underlying Token Bridge contracts on [supported chains where the TBR is available](/docs/products/connect/reference/support-matrix/){target=\_blank}. -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. + -## Emitter +### Flow of an Automatic Transfer via TBR -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +The flow of an automatic transfer using the TBR looks like this: -## Finality +1. **Initiation on the Source Chain** + The transfer begins when a user initiates a transfer on the source chain, which results in the TBR contract being called. -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. +2. **Prepare and Forward the Transfer** + The TBR verifies the token, encodes transfer details (relayer fee, native gas request, recipient), and forwards the transfer to the Token Bridge. -## Guardian +3. **Core Messaging Layer Processes the Transfer** + The Token Bridge emits a message to the Core Contract. Guardians observe the message and produce a signed VAA attesting to the transfer. -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. **Off-Chain Relayer Observes the VAA** -## Guardian Network + An off-chain relayer verifies the destination chain and token registration and then prepares to complete the transfer. -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. **Relayer Computes Native Drop-Off and Submits the VAA** -## Guardian Set - -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - -## Heartbeat - -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. - -## Observation - -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + The relayer queries the destination TBR for the native gas amount, includes it in the transaction, and submits the signed VAA. -## Relayer +6. **TBR Validates and Completes the Transfer** + + The destination TBR validates the VAA by invoking the Token Bridge contract, confirms it's from a registered TBR, verifies the token and native gas request, and then takes custody of the tokens. -A relayer is any process that delivers VAAs to a destination. +6. **Asset Distribution on the Destination Chain** -## Sequence + The TBR sends the remaining tokens and native gas to the user, pays the off-chain relayer fee, and refunds any excess native tokens. -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +The following diagram illustrates the key steps on the source chain during a transfer: -## Spy +```mermaid +sequenceDiagram + participant User + participant SourceTBR as Source Chain TBR + participant SourceTB as Source Chain Token Bridge + participant Messaging as Core Messaging Layer -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + User->>SourceTBR: Initiate transfer (token,
recipient, fees, native gas) + SourceTBR->>SourceTB: Forward transfer (burn or lock tokens) + SourceTB->>Messaging: Publish transfer message +``` -## VAA +Once the core messaging layer processes the transfer, the destination chain handles completion as shown below: + +```mermaid +sequenceDiagram + participant Messaging as Core Messaging Layer + participant Relayer as Off-chain Relayer + participant DestTBR as Destination Chain TBR + participant DestTB as Destination Chain
Token Bridge + participant DestUser as User
(Destination Chain) + + Messaging->>Relayer: Emit signed VAA for transfer + Relayer->>Relayer: Verifies destination chain and token registration + Relayer->>DestTBR: Query native gas amount + Relayer->>DestTBR: Submit signed VAA + DestTBR->>DestTB: Validate VAA + DestTBR->>DestTBR: Take custody of tokens + DestTBR->>DestUser: Send tokens (after fees & native gas) + DestTBR->>Relayer: Pay relayer fee & refund excess +``` -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +## Next Steps -## Validator +Now that you’ve seen how a transfer works try both types yourself to experience the full process: -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +- [Get Started with Token Bridge](/docs/products/token-bridge/get-started/){target=\_blank} --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/faqs/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics +title: Token Bridge FAQs +description: Find answers to common questions about the Wormhole Token Bridge, including managing wrapped assets and understanding gas fees. +categories: Token-Bridge, Transfer --- -# Infrastructure Components +# FAQs -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +## Can ownership of wrapped tokens be transferred from the Token Bridge? -## Get Started - -Start here for an overview of Wormhole architecture components and security mechanisms: - -
+No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** + - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself + - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge - --- +The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +Relevant contracts: - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) + - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} + - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} + - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} -- :octicons-book-16:{ .lg .middle } **Security** +## How do I update the metadata of a wrapped token? - --- +Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +## How do I calculate the current gas costs for Ethereum Mainnet VAA verification? - [:custom-arrow: Learn About Security](/docs/learn/security/) +You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. -
+## How can I update my wrapped token image on Solscan? -## Explore Components +Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. +--- END CONTENT --- -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +Doc-Content: https://wormhole.com/docs/products/token-bridge/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Token Bridge +description: Perform token transfers using Wormhole’s Token Bridge with the TypeScript SDK, including manual (Solana–Sepolia) and automatic (Fuji–Alfajores). +categories: Token-Bridge, Transfers +--- -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. +# Get Started with Token Bridge -## Next Steps +## Introduction -
+Wormhole's [Token Bridge](/docs/products/token-bridge/overview){target=\_blank} enables seamless multichain token transfers by locking tokens on a source chain and minting equivalent wrapped tokens on a destination chain. This mechanism preserves token properties such as name, symbol, and decimal precision across chains. -- :octicons-book-16:{ .lg .middle } **Messaging Components** +In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform two types of transfers. - --- + - **Manual transfer**: Where you control each step. + - **Automatic transfer**: Where a relayer finalizes the transfer for you. - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers +These examples will help you understand how the Token Bridge works across EVM and non-EVM chains. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +## Prerequisites -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** +Before you begin, make sure you have the following: - --- + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank} - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. +This guide uses a Solana wallet with [devnet SOL](https://faucet.solana.com/){target=\_blank} and an EVM wallet with [Sepolia ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank} for the manual transfer example, and [Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} wallets funded with testnet tokens for the automatic transfer. You can adapt the examples to match your preferred chains. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +## Configure Your Token Transfer Environment -
---- END CONTENT --- +1. Create a new directory and initialize a Node.js project: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + ```bash + mkdir token-bridge + cd token-bridge + npm init -y + ``` -# Architecture +2. Install the required dependencies: -## Overview + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +3. Create a `transfer.ts` file to handle the multichain transfer logic, and a `helper.ts` file to manage wallet signers and token utilities: -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + ```bash + touch transfer.ts helper.ts + ``` -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +4. Set up secure access to your wallets. This guide assumes you are loading your `SOL_PRIVATE_KEY` and `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +## Perform a Token Transfer + +This section shows how to run manual and automatic token transfers using a shared project structure. You will define helper utilities once and reuse them across both flows. + +In the manual transfer, you initiate a transfer on Solana, wait for Guardian signatures, and redeem the tokens on Sepolia, giving you complete control over each step. In the automatic transfer, the relayer handles attestation and redemption, simplifying the process between EVM chains. + +1. Open `helper.ts` and define utility functions to load private keys, instantiate signers for Solana and EVM chains, and retrieve token decimals as needed: + + ```ts title="helper.ts" + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, + isTokenId, + TokenId, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; + +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } + + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. +/** + * Get the number of decimals for the token on the source chain. + * This helps convert a user-friendly amount (e.g., '1') into raw units. + */ +export async function getTokenDecimals( + wh: Wormhole, + token: TokenId, + chain: ChainContext +): Promise { + return isTokenId(token) + ? Number(await wh.getDecimals(token.chain, token.address)) + : chain.config.nativeTokenDecimals; +} + + ``` - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: +2. In `transfer.ts`, add the script for your preferred transfer mode. The `automatic` flag controls transfer behavior passed to `tokenTransfer()`; set it to `false` for manual transfers and `true` for automatic transfers + + === "Manual Transfer" + + ```ts title="transfer.ts" + import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; + +(async function () { + // Initialize Wormhole SDK for Solana and Sepolia on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); + + // Define the source and destination chains + const sendChain = wh.getChain('Solana'); + const rcvChain = wh.getChain('Sepolia'); + + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Solana', 'native'); + const amt = '0.1'; + + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); + + // Set to false to require manual approval steps + const automatic = false; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); + + // Initiate the transfer from Solana + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + // Wait for the signed attestation from the Guardian network + console.log('Fetching Attestation'); + const timeout = 5 * 60 * 1000; // 5 minutes + await xfer.fetchAttestation(timeout); + + // Redeem the tokens on Sepolia + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, destTxids); + + process.exit(0); +})(); + ``` + + === "Automatic Transfer" + + ```ts title="transfer.ts" + import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; + +(async function () { + // Initialize Wormhole SDK for Avalanche and Celo on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); + + // Define the source and destination chains + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Celo'); + + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Avalanche', 'native'); + const amt = '0.2'; + + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); + + // Set to false to require manual approval steps + const automatic = true; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); + + // Initiate the transfer from Avalanche Fuji + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + process.exit(0); +})(); + ``` - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -## On-Chain Components +3. Execute the script to initiate and complete the transfer: -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + ```bash + npx tsx transfer.ts + ``` -## Off-Chain Components + If successful, the expected output should be similar to this: + +
+npx tsx transfer.ts +Starting Transfer +Started Transfer: ['36UwBBh6HH6wt3VBbNNawMd1ijCk28YgFePrBWfE3vGQFHtbMjY5626nqHubmyQWGNh2ZrN1vHKRrSQDNC3gkZgB'] + +Getting Attestation +Retrying Wormholescan:GetVaaBytes, attempt 0/900 +Retrying Wormholescan:GetVaaBytes, attempt 1/900 +Retrying Wormholescan:GetVaaBytes, attempt 2/900 + +Completing Transfer +Completed Transfer: [ '53Nt4mp2KRTk2HFyvUcmP9b6cRXjVAN3wCksoBey9WmT' ] + +
-- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers +To verify the transaction and view its details, copy the transaction hash from the output and paste it into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. ## Next Steps -
- -- :octicons-book-16:{ .lg .middle } **Core Contracts** +Now that you've completed a manual multichain token transfer, explore these guides to continue building: - --- + - [Complete Token Transfer Workflow](/docs/products/token-bridge/tutorials/transfer-workflow){target=\_blank}: Build a reusable application that supports multiple chain combinations and transfer modes (manual and automatic). + - [Create Multichain Tokens](/docs/products/token-bridge/tutorials/multichain-token){target=\_blank}: Learn how to issue tokens that work across chains. +--- END CONTENT --- - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. +Doc-Content: https://wormhole.com/docs/products/token-bridge/guides/token-bridge-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Token Bridge +description: Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. +categories: Token-Bridge, Transfer +--- - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +# Interact with Token Bridge Contracts -- :octicons-tools-16:{ .lg .middle } **Core Messaging** +## Introduction - --- +Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/protocol/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. +This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} page in the Learn section. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +## Prerequisites -
---- END CONTENT --- +To interact with the Wormhole Token Bridge, you'll need the following: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- +- [The address of the Token Bridge contract](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers -# Core Contracts +## How to Interact with Token Bridge Contracts -## Introduction +The primary functions of the Token Bridge contracts revolve around: -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. +- **Attesting a token** - registering a new token for cross-chain transfers +- **Transferring tokens** - locking and minting tokens across chains +- **Transferring tokens with a payload** - including additional data with transfers -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. +### Attest a Token -## Key Functions +Suppose a token has never been transferred to the target chain before transferring it cross-chain. In that case, its metadata must be registered so the Token Bridge can recognize it and create a wrapped version if necessary. -Key functions of the Wormhole Core Contract include the following: +The attestation process doesn't require you to manually input token details like name, symbol, or decimals. Instead, the Token Bridge contract retrieves these values from the token contract itself when you call the `attestToken()` method. -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +```solidity +function attestToken( + address tokenAddress, + uint32 nonce +) external payable returns (uint64 sequence); +``` -## How the Core Contract Works +??? interface "Parameters" -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. + `tokenAddress` ++"address"++ + + The contract address of the token to be attested. -The following describes the role of the Wormhole Core Contract in message transfers: + --- -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions + `nonce` ++"uint32"++ -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. + An arbitrary value provided by the caller to ensure uniqueness. -### Message Submission +??? interface "Returns" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + `sequence` ++"uint64"++ + + A unique identifier for the attestation transaction. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page +??? interface "Example" -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); -### Message Reception +uint256 wormholeFee = wormhole.messageFee(); -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. +tokenBridge.attestToken{value: wormholeFee}( + address(tokenImpl), // the token contract to attest + 234 // nonce for the transfer +); + ``` -## Multicast +When `attestToken()` is called, the contract emits a Verifiable Action Approval (VAA) containing the token's metadata, which the Guardians sign and publish. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. +You must ensure the token is ERC-20 compliant. If it does not implement the standard functions, the attestation may fail or produce incomplete metadata. -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. +### Transfer Tokens -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. +Once a token is attested, a cross-chain token transfer can be initiated following the lock-and-mint mechanism. On the source chain, tokens are locked (or burned if they're already a wrapped asset), and a VAA is emitted. On the destination chain, that VAA is used to mint or release the corresponding amount of wrapped tokens. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. +Call `transferTokens()` to lock/burn tokens and produce a VAA with transfer details. -## Next Steps +```solidity +function transferTokens( + address token, + uint256 amount, + uint16 recipientChain, + bytes32 recipient, + uint256 arbiterFee, + uint32 nonce +) external payable returns (uint64 sequence); +``` -
+??? interface "Parameters" -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + `token` ++"address"++ + + The address of the token being transferred. --- - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + `amount` ++"uint256"++ + The amount of tokens to be transferred. - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + --- -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + `recipientChain` ++"uint16"++ + The Wormhole chain ID of the destination chain. --- - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + `recipient` ++"bytes32"++ + The recipient's address on the destination chain. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + --- -
---- END CONTENT --- + `arbiterFee` ++"uint256"++ + Optional fee to be paid to an arbiter for relaying the transfer. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + --- -## Guardian + `nonce` ++"uint32"++ + A unique identifier for the transaction. -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +??? interface "Returns" -Guardians fulfill their role in the messaging protocol as follows: + `sequence` ++"uint64"++ + + A unique identifier for the transfer transaction. -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +??? interface "Example" -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); -## Guardian Network +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +tokenBridge.transferTokens{value: wormholeFee}( + token, // address of the ERC-20 token to transfer + amount, // amount of tokens to transfer + recipientChain, // Wormhole chain ID of the destination chain + recipient, // recipient address on the destination chain (as bytes32) + arbiterFee, // fee for relayer + nonce // nonce for this transfer +); + ``` -The Guardian Network is designed to help Wormhole deliver on five key principles: +Once a transfer VAA is obtained from the Wormhole Guardian network, the final step is to redeem the tokens on the destination chain. Redemption verifies the VAA's authenticity and releases (or mints) tokens to the specified recipient. To redeem the tokens, call `completeTransfer()`. -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +```solidity +function completeTransfer(bytes memory encodedVm) external; +``` -The following sections explore each principle in detail. +??? interface "Parameters" -### Decentralization + `encodedVm` ++"bytes memory"++ + + The signed VAA containing the transfer details. -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +!!!note + - The Token Bridge normalizes token amounts to 8 decimals when passing them between chains. Make sure your application accounts for potential decimal truncation + - The VAA ensures the integrity of the message. Only after the Guardians sign the VAA can it be redeemed on the destination chain -Two common approaches to decentralization have notable limitations: +### Transfer Tokens with Payload -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +While a standard token transfer moves tokens between chains, a transfer with a payload allows you to embed arbitrary data in the VAA. This data can be used on the destination chain to execute additional logic—such as automatically depositing tokens into a DeFi protocol, initiating a swap on a DEX, or interacting with a custom smart contract. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +Call `transferTokensWithPayload()` instead of `transferTokens()` to include a custom payload (arbitrary bytes) with the token transfer. -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +```solidity +function transferTokensWithPayload( + address token, + uint256 amount, + uint16 recipientChain, + bytes32 recipient, + uint32 nonce, + bytes memory payload +) external payable returns (uint64 sequence); +``` -To answer that, consider these key constraints and design decisions: +??? interface "Parameters" -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants + `token` ++"address"++ + + The address of the token being transferred. -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. + --- -### Modularity + `amount` ++"uint256"++ + The amount of tokens to be transferred. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. + --- -### Chain Agnosticism + `recipientChain` ++"uint16"++ + The Wormhole chain ID of the destination chain. -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. + --- -### Scalability + `recipient` ++"bytes32"++ + The recipient's address on the destination chain. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. + --- -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. + `nonce` ++"uint32"++ + A unique identifier for the transaction. -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. + --- -### Upgradeable + `payload` ++"bytes memory"++ + Arbitrary data payload attached to the transaction. -Wormhole is designed to adapt and evolve in the following ways: +??? interface "Returns" + + `sequence` ++"uint64"++ + + A unique identifier for the transfer transaction. -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +??? interface "Example" -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); -## Next Steps +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -
+tokenBridge.transferTokensWithPayload{value: wormholeFee}( + token, // address of the ERC-20 token to transfer + amount, // amount of tokens to transfer + recipientChain, // Wormhole chain ID of the destination chain + recipient, // recipient address on the destination chain (as bytes32) + nonce, // nonce for this transfer + additionalPayload // additional payload data +); + ``` -- :octicons-book-16:{ .lg .middle } **Relayers** +After initiating a transfer on the source chain, the Wormhole Guardian network observes and signs the resulting message, creating a Verifiable Action Approval (VAA). You'll need to fetch this VAA and then call `completeTransferWithPayload()`. - --- +Only the designated recipient contract can redeem tokens. This ensures that the intended contract securely handles the attached payload. On successful redemption, the tokens are minted (if foreign) or released (if native) to the recipient address on the destination chain. For payload transfers, the designated contract can execute the payload's logic at this time. - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +```solidity +function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory); +``` - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +??? interface "Parameters" -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + `encodedVm` ++"bytes memory"++ - --- + The signed VAA containing the transfer details. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +??? interface "Returns" + + `bytes memory` - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + The extracted payload data. -
+## Source Code References + +For a deeper understanding of the Token Bridge implementation and to review the actual source code, please refer to the following links: + +- [Token Bridge contract](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol){target=\_blank} +- [Token Bridge interface](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} + +## Portal Bridge + +A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/overview/ --- BEGIN CONTENT --- --- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics +title: Token Bridge Overview +description: With Wormhole Token Bridge, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Token-Bridge, Transfer --- -# Relayers +# Token Bridge Overview -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +The Token Bridge is a Wormhole module for bridging wrapped tokens across various blockchain networks. Locking assets on one network and minting corresponding wrapped tokens on another facilitates secure, efficient, and composable multichain token movement. -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +This overview covers Token Bridge's main features, general processes, and possible next steps to begin building a cross-chain application. -There are three primary types of relayers discussed: +## Key Features -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +Token Bridge is built to solve interoperability problems in multichain token transfers. Key features include: -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +- **Interoperability**: Transfer standards-compliant tokens (e.g., ERC-20, SPL) across over 30 [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank}. +- **Lock-and-mint mechanism**: Mint wrapped tokens backed 1:1 by locked assets on the source chain. +- **Preserved metadata**: Ensure that token properties like name, symbol, and decimals persist across chains. +- **Transfer with payload**: Attach arbitrary data to token transfers, enabling the triggering of specific actions. +- **Decentralized security**: Verified by the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank}, ensuring cross-chain consistency and message authenticity. -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +## How It Works -## Fundamentals +The Token Bridge provides a reliable foundation for multichain interoperability at scale. The transfer process follows these key steps: -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +1. **Attestation**: The token’s metadata (e.g., symbol, name, decimals) is registered on the destination chain. This step is only required once per token. +2. **Locking**: On the source chain, the native token is locked in a custody account. +3. **Message emission**: The [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} verifies and emits a [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +4. **Verification**: The VAA is submitted and verified on the destination chain to confirm authenticity. +5. **Minting**: A wrapped version of the token is minted (or the native token is released) to the recipient on the destination chain. -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +This diagram showcases a simplified flow of Alice bridging ETH from Ethereum to her account on Solana. -Key characteristics of VAAs include: +```mermaid +sequenceDiagram + participant Alice + participant Ethereum + participant GuardianNetwork + participant Solana -- Public emission from the Guardian Network + Alice->>Ethereum: Lock ETH in Token Bridge contract + Ethereum->>GuardianNetwork: Emit transfer message + GuardianNetwork->>GuardianNetwork: Verify and sign message -- Authentication through signatures from the Guardian Network + GuardianNetwork->>Solana: Submit signed message + Solana->>Solana: Verify message and mint wrapped ETH (WETH) -- Verifiability by any entity or any Wormhole Core Contract + Solana->>Alice: Deliver wrapped ETH on Solana +``` -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +For a more in-depth understanding of how the Token Bridge works, see the [Flow of a Transfer](/docs/products/token-bridge/concepts/transfer-flow/){target=\_blank} page. -Keep in mind the following security considerations around relayers: +## Use Cases -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +Here are key use cases that highlight the power and versatility of the Token Bridge. -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +- **Multichain Rewards and Token Utility in Decentralized Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Transfer tokens between chains. + - [**Messaging**](/docs/products/messaging/overview/): Facilitate the distribution and claiming processes of rewards. -## Client-Side Relaying +- **Tokenized Gaming Rewards** -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Handle the underlying lock-and-mint logic securely. + - [**Connect**](/docs/products/connect/overview/): Provide a user-friendly way to move game tokens across chains. -### Key Features +- **Multichain DeFi Arbitrage** -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Enables rapid and secure movement of DeFi assets. + - [**Connect**](/docs/products/connect/overview/): Provides a UI widget to onboard users and facilitate seamless multichain swaps within DeFi aggregator platforms. -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +## Next Steps -### Implementation +If you are looking for more guided practice, take a look at: -Users themselves carry out the three steps of the cross-chain process: +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/): Perform token transfers using the Token Bridge, including manual and automatic transfers. +- [**Complete Token Transfer Flow**](/docs/products/token-bridge/tutorials/transfer-workflow/): Build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains. +- [**Create Multichain Tokens**](/docs/products/token-bridge/tutorials/multichain-token/): Craft a multichain token using Wormhole's Portal Bridge. +--- END CONTENT --- -1. Perform an action on chain A +## Basics Concepts [shared: true] -2. Retrieve the resulting VAA from the Guardian Network +The following section contains foundational documentation shared across all Wormhole products. +It describes the architecture and messaging infrastructure that serve as the backbone for all integrations built with Wormhole. +This includes the core contracts, VAA (Verifiable Action Approval) structure, guardian set functionality, and message flow mechanisms. +This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. -3. Perform an action on chain B using the VAA +--- -### Considerations +## List of shared concept pages: -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -- Users must sign all required transactions with their own wallet +## Full content for shared concepts: -- Users must have funds to pay the transaction fees on every chain involved +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK +--- -- The user experience may be cumbersome due to the manual steps involved +# Get Started with Messaging -## Custom Relayers +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +## Prerequisites -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +Before you begin, ensure you have the following: -### Key Features +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## Configure Your Messaging Environment -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +1. Create a directory and initialize a Node.js project: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -### Implementation + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -### Considerations + ```bash + npx tsc --init + ``` -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -- Development work and hosting of relayers are required +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees + ```bash + npm install @wormhole-foundation/sdk + ``` -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +5. Create a new file named `main.ts`: -## Wormhole Relayers + ```bash + touch main.ts + ``` -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -### Key Features + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -- **Lower operational costs** - no need to develop, host, or maintain individual relayers + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -### Implementation + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -The Wormhole relayer integration involves two key steps: + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -### Considerations + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +2. Run the script using the following command: -- All computations are performed on-chain + ```bash + npx tsx main.ts + ``` -- Potentially less gas-efficient compared to custom relayers + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -- Support may not be available for all chains +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. ## Next Steps -
+- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- -- :octicons-book-16:{ .lg .middle } **Spy** +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +categories: Basics +--- - --- +# Get Started with Core Contracts - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +## Introduction - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - --- +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +## Prerequisites - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +To interact with the Wormhole Core Contract, you'll need the following: -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - --- +## How to Interact with Core Contracts - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -
---- END CONTENT --- +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ ---- BEGIN CONTENT --- ---- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -categories: Basics ---- +### Sending Messages -# Spy +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +=== "EVM" -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -## Key Features + ??? interface "Parameters" -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -## Integrator Use Case + --- -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. + --- -## Observable Message Categories + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -A Spy can access the following categories of messages shared over the gossip protocol: + ??? interface "Returns" -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +// Check fee and send parameters -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -## Additional Resources +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -
+ View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +=== "Solana" - --- + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} + ??? interface "Parameters" -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - --- + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** + ??? child "Type `PostMessage<'info>`" - --- + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) + --- -
+ `batch_id` ++"u32"++ + + An identifier for the message batch. -## Next Steps + --- -
+ `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -- :octicons-code-16:{ .lg .middle } **Run a Spy** + --- - --- + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -- :octicons-code-16:{ .lg .middle } **Use Queries** + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters - --- +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -
---- END CONTENT --- +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ ---- BEGIN CONTENT --- ---- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. -categories: Basics ---- +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -# Verified Action Approvals +### Receiving Messages -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. +The way a message is received and handled depends on the environment. -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +=== "EVM" -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. + ??? interface "Parameters" -## VAA Format + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -The basic VAA consists of header and body components described as follows: + ??? interface "Returns" -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. - Where each `signature` is: + ??? child "Struct `VM`" - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. + ??? interface "Example" -## Consistency and Finality + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. + // Perform safety checks here -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); -## Signatures + // Your custom application logic here +} + ``` -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) +=== "Solana" + + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + + Retrieve the raw message data: + + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` + + ??? interface "Example" + + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted + + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` + + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. + +#### Validating the Emitter + +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); ``` -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -## Payload Types +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +await tx.wait(); +``` -### Token Transfer +#### Additional Checks -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Transferring tokens from the sending chain to the destination chain requires the following steps: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +## Source Code References -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -### Attestation +# Wormhole Relayer -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +## Introduction -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -The message format for token attestation is as follows: +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +## Get Started with the Wormhole Relayer -#### Attestation Tips +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -Be aware of the following considerations when working with attestations: +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +### Wormhole Relayer Interfaces -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +## Interact with the Wormhole Relayer -### Token Transfer with Message +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +Your initial set up should resemble the following: -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -### Governance +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +contract Example { + IWormholeRelayer public wormholeRelayer; -#### Action Structure + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Send a Message -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); ``` -#### Actions +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -## Lifetime of a Message +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. + +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: + +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); + +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` + +### Receive a Message + +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). + +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` + +The logic inside the function body may be whatever business logic is required to take action on the specific payload. + +## Delivery Guarantees + +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. + +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. + +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. + +## Delivery Statuses + +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: + +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure + +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: + +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` + +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. + +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. + +## Other Considerations + +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: + +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent + +## Track the Progress of Messages with the Wormhole CLI + +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: + +=== "Mainnet" + + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` + +=== "Testnet" + + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` + +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. + +## Step-by-Step Tutorial + +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- + +# Messaging Overview + +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. + +## Key Features + +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. + +## How It Works + +The messaging flow consists of several core components: + +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. + +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) + +## Use Cases + +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. + +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. + +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. + +- **Gas Abstraction** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. + +- **Bridging Intent Library** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. + +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. + +## Next Steps + +Follow these steps to work with Wormhole Messaging: + +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- + +# Products + +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. + +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. + +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. + +## Transfer Products + +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. + +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods + +
+ +::spantable:: + +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | + +::end-spantable:: + +
+ +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: + +
+ +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. + +## Bridging UI + +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. + +## Real-time Data + +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + +## Multichain Governance + +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ +--- BEGIN CONTENT --- +--- +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +categories: Basics +--- + +# Glossary + +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. + +## Chain ID + +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. + +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. + +## Consistency Level + +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. + +## Delivery Provider + +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. + +## Emitter + +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. + +## Finality + +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + +## Guardian + +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. + +## Guardian Network + +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. + +## Guardian Set + +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. + +## Heartbeat + +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + +## Observation + +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + +## Relayer + +A relayer is any process that delivers VAAs to a destination. + +## Sequence + +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + +## Spy + +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + +## VAA + +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. + +## Validator + +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/protocol/architecture/ +--- BEGIN CONTENT --- +--- +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics +--- + +# Architecture + +## Overview + +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. + +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) + +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + +## On-Chain Components + +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + +## Off-Chain Components + +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + +## Next Steps + +
+ +- :octicons-book-16:{ .lg .middle } **Core Contracts** + + --- + + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) + +- :octicons-tools-16:{ .lg .middle } **Core Messaging** + + --- + + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +
+--- END CONTENT --- -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +# The Wormhole Ecosystem -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -## Next Steps +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-book-16:{ .lg .middle } **Guardians** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. categories: Basics --- -# Introduction to Wormhole +# Core Contracts -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +## Introduction -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +## Key Functions -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +Key functions of the Wormhole Core Contract include the following: -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +## How the Core Contract Works -## What Problems Does Wormhole Solve? +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +The following describes the role of the Wormhole Core Contract in message transfers: -Critical problems Wormhole addresses include: +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -## What Does Wormhole Offer? +### Message Submission -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -## What Isn't Wormhole? +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +### Message Reception -## Use Cases of Wormhole +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -Consider the following examples of potential applications enabled by Wormhole: +## Multicast -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -## Explore +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -Discover more about the Wormhole ecosystem, components, and protocols: +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -## Demos +## Next Steps -Demos offer more realistic implementations than tutorials: +
-- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** - + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -!!! note - Wormhole Integration Complete? + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** + --- -## Supported Blockchains + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -Wormhole supports a growing number of blockchains. + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -text/supported-networks.md +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/security/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Security +## Guardian -## Core Security Assumptions +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Guardians fulfill their role in the messaging protocol as follows: -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -In summary: +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +## Guardian Network -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## Guardian Network +The Guardian Network is designed to help Wormhole deliver on five key principles: -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Governance +The following sections explore each principle in detail. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +### Decentralization -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +Two common approaches to decentralization have notable limitations: -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -Via governance, the Guardians can: +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +To answer that, consider these key constraints and design decisions: -## Monitoring +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +### Modularity -Guardians monitor: +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +### Chain Agnosticism -## Asset Layer Protections +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +### Scalability -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -## Open Source +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -Wormhole builds in the open and is always open source. +### Upgradeable -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +Wormhole is designed to adapt and evolve in the following ways: -## Audits +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +## Next Steps -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +
-## Bug Bounties +- :octicons-book-16:{ .lg .middle } **Relayers** -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + --- -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -## Learn More + --- -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. + + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. categories: Basics --- -# Get Started with Core Contracts +# Relayers -## Introduction +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +There are three primary types of relayers discussed: -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -## Prerequisites +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -To interact with the Wormhole Core Contract, you'll need the following: +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +## Fundamentals -## How to Interact with Core Contracts +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +Key characteristics of VAAs include: -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +- Public emission from the Guardian Network -### Sending Messages +- Authentication through signatures from the Guardian Network -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +- Verifiability by any entity or any Wormhole Core Contract -=== "EVM" +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +Keep in mind the following security considerations around relayers: - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks - ??? interface "Parameters" +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain + +## Client-Side Relaying + +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + +### Key Features + +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure + +### Implementation - --- +Users themselves carry out the three steps of the cross-chain process: - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +1. Perform an action on chain A - --- +2. Retrieve the resulting VAA from the Guardian Network - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +3. Perform an action on chain B using the VAA - ??? interface "Returns" +### Considerations - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +- Users must sign all required transactions with their own wallet -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +- Users must have funds to pay the transaction fees on every chain involved -// Check fee and send parameters +- The user experience may be cumbersome due to the manual steps involved -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +## Custom Relayers -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +### Key Features -=== "Solana" +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - ??? interface "Parameters" +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +### Implementation - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +### Considerations - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - ??? child "Type `PostMessage<'info>`" +- Development work and hosting of relayers are required - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - --- +## Wormhole Relayers - `batch_id` ++"u32"++ - - An identifier for the message batch. +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - --- +### Key Features - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +- **Lower operational costs** - no need to develop, host, or maintain individual relayers - --- +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +### Implementation - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +The Wormhole relayer integration involves two key steps: - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +### Considerations -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- All computations are performed on-chain -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- Potentially less gas-efficient compared to custom relayers -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted -### Receiving Messages +- Support may not be available for all chains -The way a message is received and handled depends on the environment. +## Next Steps -=== "EVM" +
- On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +- :octicons-book-16:{ .lg .middle } **Spy** - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` + --- - ??? interface "Parameters" + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - ??? interface "Returns" +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. + --- - ??? child "Struct `VM`" + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- + --- - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - ??? interface "Example" + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +
+--- END CONTENT --- - // Perform safety checks here +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +# Spy - // Your custom application logic here -} - ``` +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. -=== "Solana" +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. +## Key Features - Retrieve the raw message data: +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +## Integrator Use Case - ??? interface "Example" +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +## Observable Message Categories - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +A Spy can access the following categories of messages shared over the gossip protocol: -#### Validating the Emitter +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -await tx.wait(); -``` +## Additional Resources -#### Additional Checks +
-In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + --- -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -## Source Code References + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- + --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. -# Wormhole Relayer + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -## Introduction +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. + --- -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -## Get Started with the Wormhole Relayer + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +
-To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +## Next Steps -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+
-### Wormhole Relayer Interfaces +- :octicons-code-16:{ .lg .middle } **Run a Spy** -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + --- -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -## Interact with the Wormhole Relayer + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. +- :octicons-code-16:{ .lg .middle } **Use Queries** -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + --- -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -Your initial set up should resemble the following: + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +
+--- END CONTENT --- -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ +--- BEGIN CONTENT --- +--- +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics +--- -contract Example { - IWormholeRelayer public wormholeRelayer; +# Verified Action Approvals - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -### Send a Message +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +## VAA Format -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +The basic VAA consists of header and body components described as follows: -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. + Where each `signature` is: -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -### Receive a Message +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +## Consistency and Finality -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -## Delivery Guarantees +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +## Signatures -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` -## Delivery Statuses +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +## Payload Types -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +### Token Transfer -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +Transferring tokens from the sending chain to the destination chain requires the following steps: -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -## Other Considerations +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -## Track the Progress of Messages with the Wormhole CLI +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +### Attestation -=== "Mainnet" +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -=== "Testnet" +The message format for token attestation is as follows: - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +#### Attestation Tips -## Step-by-Step Tutorial +Be aware of the following considerations when working with attestations: -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -# Products +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +### Token Transfer with Message -## Transfer Products +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -
+- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific -::spantable:: +### Governance -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). -::end-spantable:: +#### Action Structure -
+Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -## Bridging UI +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Real-time Data +#### Actions -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -## Multichain Governance +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +## Lifetime of a Message -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -# Wormhole Use Cases +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -
-
+1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -## Cross-Chain Swaps and Liquidity Aggregation +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -Enable seamless swaps between chains with real-time liquidity routing. +## Next Steps -
-
+
-🛠 **Wormhole products used:** +- :octicons-book-16:{ .lg .middle } **Guardians** -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution + --- -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -
-
+ [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -
-
+ --- -## Borrowing and Lending Across Chains + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -Let users borrow assets on one chain using collateral from another. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/)
-
+--- END CONTENT --- -🛠 **Wormhole products used:** +Doc-Content: https://wormhole.com/docs/protocol/introduction/ +--- BEGIN CONTENT --- +--- +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics +--- -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +# Introduction to Wormhole -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -
-
+Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -
-
+![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -## Real-Time Price Feeds and Trading Strategies +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -Fetch price feeds across multiple chains for DeFi applications. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
-
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -🛠 **Wormhole products used:** +## What Problems Does Wormhole Solve? -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Critical problems Wormhole addresses include: -
-
+- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. +## What Does Wormhole Offer? -
-
+Wormhole provides a suite of tools and protocols that support a wide range of use cases: -## Asset Movement Between Bitcoin and Other Chains +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -Enable direct BTC transfers without wrapped assets. +## What Isn't Wormhole? -
-
+- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -🛠 **Wormhole products used:** +## Use Cases of Wormhole -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +Consider the following examples of potential applications enabled by Wormhole: -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -
-
+## Explore -
-
+Discover more about the Wormhole ecosystem, components, and protocols: -## Decentralized Social Platforms +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -Enable seamless communication and asset transfer across decentralized social networks. +## Demos -
-
+Demos offer more realistic implementations than tutorials: -🛠 **Wormhole products used:** +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards + -
-
+!!! note + Wormhole Integration Complete? + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -## Memecoin Launchpads +## Supported Networks by Product -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -🛠 **Wormhole products used:** +# Security -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +## Core Security Assumptions -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -
-
+- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -## Cross-Chain Perpetuals +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +## Guardian Network -
-
+Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -🛠 **Wormhole products used:** +### Governance -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -
-
+Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: -## Gas Abstraction +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -
-
+## Monitoring -🛠 **Wormhole products used:** +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +Guardians monitor: -
-
+- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +## Asset Layer Protections + +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -## Bridging Intent Library +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +## Open Source -
-
+Wormhole builds in the open and is always open source. -🛠 **Wormhole products used:** +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +## Audits -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -
-
+- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -
-
+## Bug Bounties -## Multichain Prediction Markets +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -
-
+If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -🛠 **Wormhole products used:** +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +## Learn More -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- +# Get Started with the Solidity SDK -
-
+The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -## Cross-Chain Payment Widgets +## Install the SDK -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -
-
+```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -🛠 **Wormhole products used:** +## Key Components -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +The following key components and features work together to make your on-chain Wormhole integration easier to build. -🔗 **Used in:** E-commerce, Web3 payments, and subscription models +??? interface "Base contracts" -
-
+ Leverage base contracts to send and receive messages and tokens. + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -
-
+??? interface "Interfaces" -## Oracle Networks + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -
-
+??? interface "Constants" -🛠 **Wormhole products used:** + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +## Example Usage -
-
+The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. +### Prerequisites +Before you begin, ensure you have the following: -
-
+- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -## Cross-Chain Staking +### Set Up a Project -Enable users to stake assets on one chain while earning rewards or securing networks on another. +Follow these steps to prepare your development environment: -
-
+1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -🛠 **Wormhole products used:** + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -
-
---- END CONTENT --- +### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -## Reference Concepts [shared: true] + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); + + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); + + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` ---- + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -## List of shared concept pages: +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. +## Use Contracts to Transfer USDC -## Full content for shared concepts: +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- + ```bash + touch script/transfer.ts + ``` -# Reference +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -## Get Started +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -
+ // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - --- + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); - --- + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -2613,7 +3809,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -2668,7 +3864,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -2884,262 +4080,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -3151,7 +4181,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -3326,7 +4356,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -3407,4 +4437,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-transfer.txt b/llms-files/llms-transfer.txt index c61e51a90..7d3cf204b 100644 --- a/llms-files/llms-transfer.txt +++ b/llms-files/llms-transfer.txt @@ -13,889 +13,503 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/cctp.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/deployment.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/overview.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/security.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/architecture.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/overview.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/token-bridge.md [type: learn] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/products.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/cctp.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-data.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-theme.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/features.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/overview.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/routes.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/upgrade.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/cli-commands.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/access-control.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/rate-limiting.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/installation.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/post-deployment.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/troubleshooting.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/managers-transceivers.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/liquidity-layer.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/solver.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/token-bridge.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect.md [type: tutorials] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/react-dapp.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/tutorials/react-dapp.md [type: tutorials] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/guides/cctp-contracts.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/concepts/routes.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/data.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/theme.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/hosted-version.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/upgrade.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/reference/support-matrix.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/security.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/access-control.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/rate-limiting.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-evm.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-solana.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/evm-launchpad.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/post-deployment.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/troubleshoot.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/cli-commands.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/managers-transceivers.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/products.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/concepts/architecture.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/overview.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/transfer-flow.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/guides/token-bridge-contracts.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/overview.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/learn/transfers/ +Doc-Content: https://wormhole.com/docs/products/connect/tutorials/react-dapp/ --- BEGIN CONTENT --- --- -title: Multichain Transfers -description: This section introduces the core messaging protocols that power seamless multichain communication and asset transfer within the Wormhole ecosystem. -categories: Transfer +title: Integrate Connect into a React DApp Tutorial +description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. +categories: Connect, Transfer --- -# Multichain Transfers - -These sections include information about Wormhole's transfer products to help you learn how they work and determine the best transfer product to fit your needs. - -Use the following links to jump directly to each Wormhole transfer product information page or continue for a product comparison: - -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/) - a mechanism to transfer native tokens multichain seamlessly without converting to a wrapped asset -- [**Settlement**](/docs/learn/transfers/settlement/) - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -- [**Token Bridge**](/docs/learn/transfers/token-bridge/) - a bridging solution that uses a lock and mint mechanism - -## Compare Transfer Products - -A few key comparisons can help you readily differentiate between Wormhole transfer product offerings. Use the following sections to help compare and select products: - -### NTT vs. Token Bridge - -Understand the key differences between Native Token Transfers (NTT) and Token Bridge to determine which solution best fits your needs. - -- Native Token Transfers (NTT) move tokens in their original form without wrapping them, ensuring compatibility with on-chain applications but requiring custom contracts on both the source and destination chains -- Token Bridge locks tokens on the source chain and mints wrapped versions on the destination chain. This method does not require changes to existing token contracts and supports additional message payloads for more complex use cases - -
- -| Supports | NTT | Token Bridge | -|---------------------------|--------------------|--------------------| -| Message Payload | :white_check_mark: | :white_check_mark: | -| Wrapped Assets | :x: | :white_check_mark: | -| Native Assets | :white_check_mark: | :x: | -| Contract-Free Development | :x: | :white_check_mark: | -| User-Owned Contracts | :white_check_mark: | :x: | - -
- -In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - -
- +# Integrate Connect into a React DApp -### Settlement +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -Settlement enables fast and efficient multichain transfers by optimizing liquidity without relying on traditional bridging methods. Unlike NTT, which moves native assets directly between chains, and Token Bridge, which locks tokens and mints wrapped versions, Settlement uses intent-based execution. Users specify the desired transfer outcome, and solvers compete to fulfill it most efficiently. +## Introduction -By leveraging a decentralized solver network, Settlement ensures efficient cross-chain liquidity without locking assets or requiring asset wrapping, providing a seamless and capital-efficient solution for multichain transactions. +In this tutorial, we'll explore how to integrate [Wormhole Connect](/docs/products/connect/overview/){target=\_blank} to enable cross-chain token transfers and interactions. Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. -## Additional Resources +While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any [blockchain supported by Wormhole](/docs/products/connect/reference/support-matrix/){target=\_blank}. In this example, we'll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. -
+## Prerequisites -- :octicons-tools-16:{ .lg .middle } **Product Comparison** +To get started with Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. +Before starting this tutorial, ensure you have the following: - --- +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use +- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} +- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees - Compare Wormhole's multichain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +## Set Up Connect for Sui Transfers - [:custom-arrow: Compare Products](/docs/build/start-building/products/#transfer-products) +### Create a React Project -- :octicons-book-16:{ .lg .middle } **Use Cases** +In this tutorial, we'll use [Next.js](https://nextjs.org/docs/app/getting-started){target=\_blank}, a popular framework built on top of React, to set up your app: - --- +1. Open your terminal and run the following command to create a new React app: - Explore Wormhole's use cases, from multichain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. + ```bash + npx create-next-app@latest connect-tutorial + ``` - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) + We recommend enabling TypeScript and creating a `src/` directory during setup. Other options can be configured based on your preferences. +2. Navigate into the project directory: -
---- END CONTENT --- + ```bash + cd connect-tutorial + ``` -Doc-Content: https://wormhole.com/docs/learn/transfers/cctp/ ---- BEGIN CONTENT --- ---- -title: Circle's CCTP Bridge -description: Unlock fast USDC transfers with Wormhole's integration of Circle's CCTP, featuring automatic relaying via the Wormhole relayer and native gas solutions. -categories: Transfer ---- -# Circle's CCTP Bridge +### Install Connect -Wormhole Connect and the Wormhole TypeScript SDK support fast, cheap, native USDC bridging between all networks supported by Circle's [Cross-Chain Transfer Protocol](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. CCTP is Circle's native USDC cross-chain transfer attestation service. +Next, install the Connect package as a dependency by running the following command inside your project directory: -While this protocol is wholly separate from Wormhole itself, Wormhole builds on top of CCTP and adds several valuable augmentations, making it more straightforward to use and more useful for end users. These features include: +```bash +npm install @wormhole-foundation/wormhole-connect +``` -- **Automated relaying** - eliminates the need for users to redeem USDC transfers themselves -- **Gas payment on the destination chain** - allows users to transfer USDC without needing to pay gas on the destination chain -- **Gas drop off** - enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer +### Integrate Connect into the Application -!!! note - Wormhole supports all CCTP-supported chains but at the moment only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank} are supported by Circle. +Now, we need to modify the default `page.tsx` file to integrate Connect. We are going to use [version V1.0](/docs/products/connect/guides/upgrade/){target=\_blank} or later, make sure to check which version of Connect you are using. Open `src/app/page.tsx` and replace the content with the following code: -You can use Wormhole's CCTP-powered USDC bridging by embedding the [Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or by integrating the [TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} directly. +=== "JavaScript" -## Automatic Relaying + ```js + 'use client'; -To complete a CCTP transfer, the [Circle Attestation](https://developers.circle.com/api-reference/stablecoins/common/get-attestation){target=\_blank} must be delivered to the destination chain. +import WormholeConnect from '@wormhole-foundation/wormhole-connect'; -This attestation delivery may be difficult or impossible in some contexts. For example, in a browser context, the user doesn't wish to wait for finality to deliver the attestation. To address this difficulty, the Wormhole CCTP relayer may be used either with the [Wormhole Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or more directly with the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank}. +const config = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], +}; -The Wormhole CCTP Relayer charges a fee to deliver the attestation and complete the transfer. +const theme = { + mode: 'light', + primary: '#78c4b6', +}; -| Chain | Fee | -|:---------------:|:---------------:| -| Ethereum | 1.0 USDC | -| Everything else | 0.1 USDC | +export default function Home() { + return ; +} + ``` - +=== "TypeScript" -## Native Gas Drop Off + ```ts + 'use client'; -Another advantage of using the automatic relaying feature is the opportunity to transfer some native gas to the receiver on the destination chain. This feature is referred to as _native gas drop off_. +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; -The ability to perform native gas drop off addresses the common issue where a user may hold a balance of USDC but has no native gas to perform subsequent transactions. +export default function Home() { + const config: WormholeConnectConfig = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], - ---- END CONTENT --- + ui: { + title: 'SUI Connect TS Demo', + }, + }; -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/ ---- BEGIN CONTENT --- ---- -title: A Quick Look at Native Token Transfers -description: This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- + const theme: WormholeConnectTheme = { + mode: 'light', + primary: '#78c4b6', + }; + return ; +} + ``` -# Native Token Transfers +- Set `network` to `'Testnet'` - this ensures that Connect uses the testnet environment +- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche -## Get Started +### Customize Connect -This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. +To further customize Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Connect Configuration guide](/docs/products/connect/configuration/data/){target=\_blank}. -
+### Run the Application -- :octicons-question-16:{ .lg .middle } **Overview** +Make sure you're in the root directory of your React app, and run the following command to start the application: - --- +```bash +npm run dev +``` - Dive into an introduction to NTT and discover what NTT is, what its key features are, and the available integration paths. +Now your React app should be up and running, and Connect should be visible on `http://localhost:3000/`. You should see the Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. - [:custom-arrow: Learn more about NTT](/docs/learn/transfers/native-token-transfers/overview/) +## Transfer Tokens from Sui to Fuji -- :octicons-question-16:{ .lg .middle } **Architecture** +Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. - --- +To transfer tokens from Sui to Fuji in the Connect interface: - Explore NTT's architecture to understand its core components and how they work together to manage cross-chain communication. +1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer +2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network +3. Enter the amount of SUI tokens you wish to transfer - [:custom-arrow: Discover how NTT works](/docs/learn/transfers/native-token-transfers/architecture/) + ![](/docs/images/products/connect/tutorials/react-dapp/connect-1.webp){.half} -- :octicons-book-16:{ .lg .middle } **Deployment Models** +4. Choose to view other routes + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-2.webp){.half} - --- +5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) - The NTT framework offers two deployment models for different token management needs: the hub-and-spoke and burn-and-mint models. + !!! note + It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. - [:custom-arrow: Check out the deployment models](/docs/learn/transfers/native-token-transfers/deployment/) + ![](/docs/images/products/connect/tutorials/react-dapp/connect-3.webp){.half} -- :octicons-shield-lock-16:{ .lg .middle } **Security** +6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain - --- + ![](/docs/images/products/connect/tutorials/react-dapp/connect-4.webp){.half} - Explore NTT's security measures, including the Global Accountant and governance strategies for seamless token safety. +7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet - [:custom-arrow: Review the security measures](/docs/learn/transfers/native-token-transfers/security/) + ![](/docs/images/products/connect/tutorials/react-dapp/connect-5.webp){.half} -
+Once the transaction has been submitted, Connect will display the progress of the transfer. Monitor the status until you're prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. -## Next Steps +## Claim Tokens on Fuji -Ready to dive in and start building? Check out the following resources to begin the deployment process and make the most of your deployment. +After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. -
+![](/docs/images/products/connect/tutorials/react-dapp/connect-6.webp){.half} -- :octicons-rocket-16:{ .lg .middle } **Deploy NTT** +Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. - --- +![](/docs/images/products/connect/tutorials/react-dapp/connect-7.webp){.half} - Explore detailed guides that walk you through the entire deployment process, from installing the NTT CLI to deploying NTT across supported chains. +## Resources - [:custom-arrow: Deploy now using the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/) +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. -- :octicons-checklist-16:{ .lg .middle } **Post Deployment Recommendations** +## Conclusion - --- +In this tutorial, you've gained hands-on experience with integrating Connect to enable cross-chain token transfers. You've learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. - Already deployed your NTT project? Check out these post deployment recommendations and integration demos to get the most out of your deployment. +By following these steps, you've learned how to: - [:custom-arrow: Get the most of out your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) +- Set up a React project tailored for cross-chain transfers +- Install and configure Connect to support multiple blockchains +- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers +- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks -
+With these tools and knowledge, you're now equipped to build powerful cross-chain applications using Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/architecture/ +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/get-started/ --- BEGIN CONTENT --- --- -title: Native Token Transfers Architecture -description: Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. -categories: NTT, Transfer +title: Get Started with CCTP +description: Transfer USDC across chains using Wormhole's CCTP integration with the TypeScript SDK, including setup, attestation, and redemption steps. +categories: Transfer --- -## Introduction - -The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. - -For the technical implementations of the functions, refer to the [Managers and Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/){target=\_blank} page. - -## System Components - -The NTT framework is composed of managers, which oversee the transfer process, and transceivers, which handle cross-chain messaging, ensuring smooth and reliable token transfers. - -### Managers - -_Managers_ are responsible for handling the flow of token transfers between different blockchains and ensuring that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. The main tasks of managers include rate-limiting transactions, verifying message authenticity (message attestation), and managing the interaction between multiple transceivers, who are responsible for cross-chain communications. - -Each manager is assigned to a specific token but can operate across multiple chains. Their key responsibility is to ensure that tokens are securely locked or burned on the source chain before being minted or unlocked on the destination chain. This provides the integrity of token transfers and prevents double-spending. - -A manager is responsible for: - -- **Handling token transfer flow** - upon a transfer request, `NttManager` either locks or burns tokens depending on the configuration, emits a `TransferSent` event, and ensures tokens can’t be accessed on the source chain before leasing them on the destination chain. This process safeguards against double-spending and maintains a secure transfer -- **Rate-limiting** - the `NttManager` contract includes rate-limiting functionality to prevent overloading the network or flooding the target chain. The `NttManager` applies rate limits to manage transfer flow and prevent network congestion. Limits apply to both outgoing and incoming transfers - - **Outbound** - transfers exceeding the outbound limit are queued (if `shouldQueue` is true) or reverted - - **Inbound** - similar limits apply on the destination chain, delaying transfers if capacity is exceeded - - Rate limit duration and queuing are customizable per chain, and events notify users when transfers hit the limit - -- **Message authenticity verification** - the `NttManager` ensures transfer security by verifying message authenticity through multiple attestations from transceivers. For each transfer, a threshold number of attestation signatures must be gathered from transceivers. Once verified, `NttManager` releases tokens on the destination chain, ensuring only authenticated transfers are processed -- **Interaction with transceivers** - `NttManager` collaborates with transceivers, forwarding transfer messages between chains and handling message verification. Transceivers route messages with transfer details to the destination chain, coordinating with `NttManager` to verify that tokens are locked or burned before releasing them on the other side. Transceivers can be customized to work with different security protocols, adding flexibility - -### Transceivers - -_Transceivers_ facilitate cross-chain token transfers by ensuring the accurate transmission of messages between different blockchains. They work in conjunction with managers to route token transfers from the source chain to the recipient chain. Their primary function is to ensure that messages regarding the transfer process are delivered correctly, and that tokens are safely transferred across chains. - -While transceivers operate closely with Wormhole's ecosystem, they can also be configured independently of Wormhole's core system, allowing for flexibility. This adaptability allows them to be integrated with various verification backends to accommodate different security needs or platform-specific requirements. - -Transceivers are entrusted with several responsibilities: - -- **Message transmission** - transceivers handle the routing of transfer messages between chains. When a transfer is initiated, the transceiver sends the message (including transfer details like recipient and amount) to the destination chain’s manager for verification and processing -- **Manager coordination** - transceivers work with managers to ensure tokens are locked or burned on the source chain before issuance on the destination chain, reinforcing the security of each transfer -- **Custom verification support** - transceivers can integrate with custom verification backends, allowing flexibility to adapt to different security protocols or chain requirements. This customization enables protocols to use different attestation standards as needed - -How it works: +# Get Started with CCTP -1. The transceiver receives instructions from the manager to send messages across chains -2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred -3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain +## Introduction -![NTT architecture diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-1.webp) +[Wormhole CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} enables native USDC transfers between supported chains by burning tokens on the source chain and minting them on the destination. This provides native, canonical USDC movement without the need for wrapped tokens. -!!! note - [Learn more](/docs/learn/transfers/native-token-transfers/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. +In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform a manual cross-chain USDC transfer using Circle's CCTP protocol. -#### Custom Transceivers +You will initiate the transfer on the source chain, wait for Circle's attestation, and redeem the USDC on the destination chain. -The NTT framework supports advanced features such as custom transceivers for specialized message verification, enhancing security and adaptability. The architecture includes detailed processes for initiating transfers, managing rate limits, and finalizing token operations, with specific instructions and events outlined for EVM-compatible chains and Solana. +## Prerequisites -NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. +Before you begin, make sure you have the following: -![Custom Attestation with NTT diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-2.webp) + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with native tokens and USDC on two [supported CCTP chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} -The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. +This example uses an Avalanche Fuji wallet with [USDC](https://faucet.circle.com/){target=\_blank} and [AVAX](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank}, as well as a Sepolia wallet with testnet [ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank}, to pay the transaction fees. You can adapt the steps to work with any [supported EVM chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} that support CCTP. -For more details, to collaborate, or to see examples of custom transceivers, [contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors. +## Configure Your Token Transfer Environment -## Lifecycle of a Message +1. Create a new directory and initialize a Node.js project: -The lifecycle of a message in the Wormhole ecosystem for Native Token Transfers (NTT) involves multiple steps to ensure secure and accurate cross-chain token transfers. This lifecycle can vary depending on the blockchain being used, and the following explanations focus on the EVM and Solana implementations. The key stages include initiating the transfer, handling rate limits, sending and receiving messages, and finally, minting or unlocking tokens on the destination chain. + ```bash + mkdir cctp-bridge + cd cctp-bridge + npm init -y + ``` -### Transfer +2. Install the required dependencies: -The process begins when a client initiates a transfer. For EVM, this is done using the `transfer` function, whereas in Solana, the client uses either the `transfer_lock` or `transfer_burn` instruction, depending on whether the program is in locking or burning mode. The client specifies the transfer amount, recipient chain ID, recipient address, and a flag (`should_queue` on both EVM and Solana) to decide whether the transfer should be queued if it hits the rate limit. + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` -In both cases: +3. Create a `transfer.ts` file to handle the multichain transfer logic and a `helper.ts` file to manage wallet signers: -- If the source chain is in locking mode, the tokens are locked on the source chain to be unlocked on the destination chain -- If the source chain is in burning mode, the tokens are burned on the source chain, and new tokens are minted on the destination chain + ```bash + touch transfer.ts helper.ts + ``` -Once initiated, an event (such as `TransferSent` on EVM or a corresponding log on Solana) is emitted to signal that the transfer process has started. +4. Set up secure access to your wallets. This guide assumes you are loading your `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. -### Rate Limit + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. -Both EVM and Solana implement rate-limiting for transfers to prevent abuse or network overload. Rate limits apply to both the source and destination chains. If transfers exceed the current capacity, depending on whether the `shouldQueue` flag is set to true, they can be queued. +## Perform a CCTP Transfer -- On EVM, the transfer is added to an outbound queue if it hits the rate limit, with a delay corresponding to the configured rate limit duration. If `shouldQueue` is set to false, the transfer is reverted with an error -- On Solana, the transfer is added to an **Outbox** via the `insert_into_outbox method`, and if the rate limit is hit, the transfer is queued with a `release_timestamp`. If `shouldQueue` is false, the transfer is reverted with a `TransferExceedsRateLimit` error +This section walks you through a complete manual USDC transfer using Wormhole's CCTP integration. You will initiate the transfer on Avalanche Fuji, wait for the Circle attestation, and complete the redemption on Sepolia. -Both chains emit events or logs when transfers are rate-limited or queued. +Start by defining utility functions for signer and token setup: -### Send +1. In `helper.ts`, define functions to load private keys and instantiate EVM signers: -After being forwarded to the Transceiver, the message is transmitted across the chain. Transceivers are responsible for delivering the message containing the token transfer details. Depending on the Transceiver's implementation, messages may be routed through different systems, such as Wormhole relayers or other custom relaying solutions. Once the message is transmitted, an event is emitted to signal successful transmission. + ```ts title="helper.ts" + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; -- In EVM, the message is sent using the `sendMessage` function, which handles the transmission based on the Transceiver's implementation. The Transceiver may use Wormhole relayers or custom relaying solutions to forward the message -- In Solana, the transfer message is placed in an Outbox and released via the `release_outbound` instruction. The Solana transceiver, such as the Wormhole Transceiver, may send the message using the `post_message` instruction, which Wormhole Guardians observe for verification +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } -In both cases, an event or log (e.g., `SendTransceiverMessage` on EVM or a similar log on Solana) is emitted to signal that the message has been transmitted. + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` -### Receive +2. In `transfer.ts`, add the script to perform the manual transfer using CCTP: + + ```ts title="transfer.ts" + import { CircleTransfer, wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { getSigner } from './helper'; + +(async function () { + // Initialize the Wormhole object for the Testnet environment and add supported chains (evm, solana and sui) + const wh = await wormhole('Testnet', [evm, solana, sui]); + + // Grab chain Contexts -- these hold a reference to a cached rpc client + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Sepolia'); + + // Get signer from local key + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); + + // Define the amount of USDC to transfer (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) + const amt = 100_000n; + + const automatic = false; + + // Create the circleTransfer transaction (USDC-only) + const xfer = await wh.circleTransfer( + amt, + source.address, + destination.address, + automatic + ); + + const quote = await CircleTransfer.quoteTransfer( + sendChain, + rcvChain, + xfer.transfer + ); + console.log('Quote: ', quote); + + // Step 1: Initiate the transfer on the source chain (Avalanche) + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + // Step 2: Wait for Circle Attestation (VAA) + const timeout = 120 * 1000; // Timeout in milliseconds (120 seconds) + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(timeout); + console.log(`Got Attestation: `, attestIds); + + // Step 3: Complete the transfer on the destination chain (Sepolia) + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, dstTxids); + + process.exit(0); +})(); + ``` -Upon receiving the message on the destination chain, an off-chain relayer forwards the message to the destination Transceiver for verification. +3. Run the script to execute the transfer: -- In EVM, the message is received by the `NttManager` on the destination chain, which verifies the message's authenticity. Depending on the M of N threshold set for the attestation process, the message may require attestations from multiple transceivers -- In Solana, the message is received via the `receive_message` instruction in the Wormhole Transceiver program. The message is verified and stored in a `VerifiedTransceiverMessage` account, after which it is placed in an Inbox for further processing + ```bash + npx tsx transfer.ts + ``` -In both chains, replay protection mechanisms ensure that a message cannot be executed more than once. Events or logs are emitted (e.g., `ReceivedMessage` on EVM or `ReceiveMessage` on Solana) to notify that the message has been successfully received. + You will see terminal output similar to the following: + +
+npx tsx transfer.ts +Starting Transfer +Started Transfer: + [ '0xdedbf496a1e658efb15bc57f120122b38a3714a560892be7a8c0a7f23c44aca2', + '0x9a8e41837e225edfa62d1913f850c01bd0552e55bf082fd9225df789455a465a' ] + +Waiting for Attestation +Retrying Circle:GetAttestation, attempt 0/60 +Retrying Circle:GetAttestation, attempt 1/60 + +Got Attestation: [{hash: '0x89f8651bf94cfd932ba5bcd2f7795a3fabc6a7c602075fa712c9c55022f5cca8'}] + +Completing Transfer +Completed Transfer: + [ '0x9b81bb30d2a68aa2ecc707a8a1b5af63448223a69b2ead6cf6d172ab880ad0c9'] + +
-### Mint or Unlock +To verify the transaction and view its details, paste the transaction hash into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. -Finally, after the message is verified and attested to, the tokens can be either minted (if they were burned on the source chain) or unlocked (if they were locked). The tokens are then transferred to the recipient on the destination chain, completing the cross-chain token transfer process. +## Next Steps -- On EVM, tokens are either minted (if burned on the source chain) or unlocked (if locked on the source chain). The `TransferRedeemed` event signals that the tokens have been successfully transferred -- On Solana, the tokens are unlocked or minted depending on whether the program is in locking or burning mode. The `release_inbound_unlock` or `release_inbound_mint` instruction is used to complete the transfer, and a corresponding log is produced +Now that you've completed a CCTP USDC transfer using the Wormhole SDK, you're ready to explore more advanced features and expand your integration: -In both cases, once the tokens have been released, the transfer process is complete, and the recipient receives the tokens. Events are emitted to indicate that the transfer has been fully redeemed. + - [**Circle CCTP Documentation**](https://developers.circle.com/stablecoins/cctp-getting-started): Learn how USDC cross-chain transfers work and explore advanced CCTP features. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/deployment/ +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/guides/cctp-contracts/ --- BEGIN CONTENT --- --- -title: Native Token Transfers - Deployment Models -description: Explore Wormhole's Native Token Transfers deployment models——hub-and-spoke, burn-and-mint——for seamless cross-chain token transfers. -categories: NTT, Transfer +title: Interacting with CCTP Contracts +description: Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. +categories: Transfer --- -# Deployment Models - -The Wormhole framework offers two deployment models, each catering to different token management needs: the hub-and-spoke model and the burn-and-mint model. These models provide flexible solutions for both existing token deployments and new projects looking to enable secure and seamless multichain token transfers. - -## Hub-and-Spoke +# Interact with CCTP Contracts -The hub-and-spoke model involves locking tokens on a central hub chain and minting them on destination spoke chains. This model maintains the total supply on the hub chain and is backward-compatible with any existing token deployment. - -This model is ideal for existing token deployments that don't want to alter existing token contracts. It maintains the canonical balance on a hub chain while allowing for secure native deployment to new blockchains. - -- **Hub chain** - tokens are locked when initiating a transfer -- **Spoke chains** - Equivalent tokens are minted on the destination chain +## Introduction -When transferring tokens back to the original hub chain, the tokens on the source spoke chain are burned, and the previously locked tokens on the hub chain are unlocked. However, when transferring tokens directly between spoke chains, the tokens are burned on the source spoke chain and minted on the destination spoke chain. +Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/products/cctp-bridge/overview/){target=\_blank} is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. -## Burn-and-Mint +As decentralized finance (DeFi) protocols evolve, the need for flexible, secure cross-chain messaging has expanded, requiring solutions beyond simple asset transfers. Wormhole enhances CCTP's capabilities by allowing developers to compose more complex cross-chain interactions. With Wormhole's generic messaging, applications can execute smart contract logic alongside native USDC transfers, enabling richer, more versatile cross-chain experiences. -The burn-and-mint model involves burning tokens on the source chain and minting them on the destination chain. This results in a simplified multichain transfer process that distributes the total supply across multiple chains and produces a native multichain token. +This guide will walk you through getting started with Wormhole's CCTP contracts and show you how to integrate CCTP into your smart contracts, enabling the composition of advanced cross-chain functions with native USDC transfers. -This model best suits new token deployments or projects willing to upgrade existing contracts. +## Prerequisites -- **Source chain** - tokens are burned when initiating a transfer -- **Destination chain** - equivalent tokens are minted on the destination chain ---- END CONTENT --- +To interact with the Wormhole CCTP, you'll need the following: -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/overview/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Overview -description: Explore Wormhole's Native Token Transfers for flexible cross-chain transfers with full control over token behavior, security, and integration features. -categories: NTT, Transfer ---- +- [The address of the CCTP contract](/docs/products/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -# Native Token Transfers +## Wormhole's CCTP Integration Contract -!!!tip "Looking to deploy NTT?" - If you're ready to deploy NTT or access the CLI, follow the detailed [NTT Deployment Section](/docs/build/transfers/native-token-transfers/deployment-process/){target=\_blank}. +Wormhole's Circle Integration contract, `CircleIntegration.sol`, is the contract you'll interact with directly. It burns and mints Circle-supported tokens by using [Circle's CCTP contracts](#circles-cctp-contracts). - - For deployment steps on EVM, visit the [Deploy to EVM page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} - - For deployment steps on Solana, visit the [Deploy to Solana page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/){target=\_blank} +The Circle Integration contract emits Wormhole messages with arbitrary payloads to allow additional composability when performing cross-chain transfers of Circle-supported assets. -## Introduction +This contract can be found in [Wormhole's `wormhole-circle-integration` repository](https://github.com/wormhole-foundation/wormhole-circle-integration/){target=\_blank} on GitHub. -Wormhole's Native Token Transfers (NTT) is an open source, flexible, and composable framework for transferring tokens across blockchains. By eliminating wrapped assets, NTT preserves each token’s native properties across chains, letting you maintain complete control over metadata, ownership, upgrade authority, and other custom features. +!!! note + Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/products/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. -The framework offers two modes of operation for existing token deployments. In locking mode, the original token supply is preserved on a single chain. In contrast, the burning mode enables the deployment of multichain tokens, distributing the supply across various chains. +??? code "Circle Integration contract" + ```solidity + // SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.19; -## Key Features +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IWormhole} from "wormhole/interfaces/IWormhole.sol"; +import {BytesLib} from "wormhole/libraries/external/BytesLib.sol"; -Wormhole's Native Token Transfers (NTT) framework offers a comprehensive and flexible solution for seamless token transfers across blockchains. Below are some of the key features that make this framework stand out: +import {ICircleBridge} from "../interfaces/circle/ICircleBridge.sol"; -- **No wrapped tokens** – tokens remain native on every chain where NTT is deployed. All token properties and metadata remain consistent, avoiding any confusion or overhead introduced by wrapped tokens -- **Unified user experience** - tokens retain their properties on each chain, remaining completely fungible and ensuring a consistent user experience -- **No liquidity pools** - transfer tokens without the need for liquidity pools, avoiding fees, slippage, and MEV risk -- **Integrator flexibility** - retained ownership, upgrade authority, and complete customizability over token contracts -- **Advanced rate limiting** - inbound and outbound rate limits are configurable per chain and over arbitrary periods, preventing abuse while managing network congestion and allowing for controlled deployments to new chains -- **Global Accountant** - ensures accounting integrity across chains by checking that the number of tokens burned and transferred out of a chain never exceeds the number of tokens minted -- **Access control** - to prevent unauthorized calls to administrative functions, protocols can choose to assign specific functions, such as the Pauser role, to a separate address from the owner -- **Maximum composability** - open source and extensible for widespread adoption and integration with other protocols -- **Custom attestation** - optionally add external verifiers and configure custom message attestation thresholds - -## Integration Paths - -Integrators looking to deploy their token to connected chains can use the NTT framework or the Token Bridge. Both options carry a distinct integration path and feature set depending on your requirements, as outlined in the following sections. - -### Native Token Transfers Framework - -The Native Token Transfers Framework is highly customizable and ideal for applications such as a DeFi governance token deployed across multiple chains, which seeks to achieve fungible multichain liquidity and direct integration into governance processes. - -- **Mechanism** - can entirely utilize a burn-and-mint mechanism or can be paired for a hub-and-spoke model -- **Security** - fully configurable rate limiting, pausing, access control, and threshold attestations. Integrated with the Global Accountant -- **Contract ownership** - retain ownership and upgrade authority of token contracts on each chain -- **Token contracts** - native contracts owned by your protocol governance -- **Integration** - streamlined, customizable framework allows for more sophisticated and bespoke deployments - -The following example projects demonstrate the use of the Wormhole NTT framework through Wormhole Connect and the TypeScript SDK: - -- [NTT Connect](https://github.com/wormhole-foundation/demo-ntt-connect){target=\_blank} -- [NTT TS SDK](https://github.com/wormhole-foundation/demo-ntt-ts-sdk){target=\_blank} - -### Token Bridge - -The Token Bridge offers a secure, low-effort integration suitable for applications like a Web3 game that wants to make its token tradable across multiple chains. - -- **Mechanism** - solely utilizes a lock and mint model. Unlike NTT, the Token Bridge issues a wrapped asset on the destination chain, rather than preserving the original token contract -- **Security** - preconfigured rate limiting and integrated Global Accountant -- **Contract ownership** - Token Bridge contracts are upgradeable via [Wormhole Governance](/docs/learn/security/){target=\_blank} -- **Token contracts** - wrapped asset contract owned by the Wormhole Token Bridge contract, upgradeable via a 13/19 Guardian governance process -- **Integration** - straightforward and permissionless method to deploy on multiple chains - -!!! note - [Learn more](/docs/learn/infrastructure/vaas/){target=\_blank} about the core messaging primitives in the Wormhole network. - -## Supported Token Standards - -Native Token Transfers (NTT) in Wormhole primarily support **ERC-20 tokens**, the most widely used standard for fungible tokens on the Ethereum network and other EVM-compatible blockchains. The NttManager contract leverages the IERC20 interface and SafeERC20 utility from OpenZeppelin to ensure secure and efficient token transfers. Additionally, it supports ERC-20 Burnable tokens, allowing tokens to be burned on the source chain when needed for cross-chain transfers. At this time, NTT focuses on ERC-20 tokens, and other token standards, such as ERC-721 (non-fungible tokens) or ERC-1155 (multi-token standard), are not natively supported. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/security/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Security -description: Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. -categories: NTT, Transfer ---- - -# Security - -## Global Accountant - -The Global Accountant is a defense-in-depth security feature that checks the integrity of every token transfer. It ensures that chain balances remain isolated and more tokens cannot be burned and transferred out of a chain than were ever minted. - -This feature ensures native asset fungibility remains in 1:1 parity. At no time will assets coming from a spoke chain exceed the number of native assets sent to that spoke chain. The Guardians, with their role in enforcing accounting transparency, provide a reassuring layer of security, attesting to a Native Token Transfer (NTT) only if it passes integrity checks. - -[Contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors if you are interested in configuring the Global Accountant for your multichain deployment. - -## Governance and Upgradeability - -Integrators should implement governance mechanisms to manage the addition and removal of transceivers and to upgrade contracts using proxy patterns, as demonstrated in the upgrade functions in the `NttManager` contracts. These processes can also set thresholds and rules for attestation and message approval. - -The registry component of the NTT system is crucial for maintaining a trusted list of transceivers and managing their status. Governance processes for the following actions can be submitted directly to the corresponding contract on-chain, whether it is one or multiple of the bridging contracts or one of the token contracts: - -- Adding or removing a transceiver address from the registry -- Setting the token contract address on a bridging contract -- Setting the Wormhole Core Contract address on a bridging contract -- Setting the registered bridging contract address on the token contract - -This governance model ensures that the system remains secure while being adaptable to new requirements in any environment where it is deployed. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement -description: Learn about Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. -categories: Settlement, Transfer ---- - -# Wormhole Settlement - -## Get Started - -This section covers Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. - -
- -- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. - - [:custom-arrow: Learn more about Wormhole Settlement](/docs/learn/transfers/settlement/overview/) - -- :octicons-question-16:{ .lg .middle } **Protocol Architectures** - - --- - - Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP — for scalable, efficient cross-chain asset transfers. - - [:custom-arrow: Discover protocol architectures](/docs/learn/transfers/settlement/architecture/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/architecture/ ---- BEGIN CONTENT --- ---- -title: Settlement Protocol Architecture -description: Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. -categories: Settlement, Transfer ---- - -# Settlement Protocol Architecture - -## Introduction - -This page describes the high-level mechanics of the underlying native swap protocols in the Wormhole SDK. While built on Wormhole messaging, each protocol uses a novel architecture with unique price discovery, scalability, and latency tradeoffs. These designs enable redundancy to handle highly asymmetric flows and sharp volume changes. These sections will cover the following: - -- **Wormhole Liquidity Layer** - a cross-chain transfer protocol that utilizes Solana as the central orchestration layer for cross-chain intents, allowing solvers to deploy liquidity from a single Solana-based hub rather than distributing it across each supported chain -- **Mayan Swift** - a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent -- **Mayan MCTP** - a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains - -## Wormhole Liquidity Layer - -Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster-than-finality transfers across the Wormhole ecosystem through a novel, Solana-based hub-and-spoke architecture. The hub-and-spoke model leverages interoperable token standards like Circle's CCTP (and Wormhole's NTT), allowing the solver to natively mint and burn assets between chains for intent fulfillment. This architecture allows solvers to facilitate cross-chain transfers by fronting assets on the destination chain and assuming the finality risk of the originating source chain transaction. - -Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. - -![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/learn/transfers/settlement/architecture/architecture-1.webp) - -The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. - -### Solvers and Liquidity Fragmentation - -Traditional intent-based protocols require solvers to distribute their capital across each supported chain in the network. This liquidity fragmentation leads to capital inefficiency and requires complex rebalancing to manage asymmetric flows between chains. As the number of chains increases, solvers face scalability challenges, which can result in market concentration, reducing competition and potentially impacting price discovery in intent execution. - -Using a hub-and-spoke model, the Wormhole Liquidity Layer solves these challenges by consolidating solver liquidity on a single chain, Solana. This model eliminates the need for complex cross-chain rebalancing and simplifies solvers' infrastructure requirements. Solvers only need to consider the finality risk of the originating source chain transaction and the payload size when bidding on transfers. By concentrating liquidity on Solana, the protocol can handle large transfer volumes with a smaller capital base, enhancing capital efficiency and lowering barriers to entry for solvers. This approach promotes competition, improves overall market efficiency, and ultimately benefits users with better prices while still preserving the speed of transactions. - -### Enable Unified Liquidity - -The novel hub-and-spoke liquidity architecture relies on interoperable token standards that enable cross-chain token fungibility, such as Circle's Cross-Chain Transfer Protocol (CCTP) and Wormhole's Native Token Transfers (NTT). These protocols allow assets to move seamlessly between chains, making unified liquidity possible. On the liquidity hub (Solana), solvers concentrate their liquidity in NTT or CCTP-supported assets, such as USDC. These assets act as the shuttle between chains but may not necessarily be the user's original or final asset. - -After the Solana auction concludes, the appropriate instructions are called on the CCTP or NTT contract, initiating the transfer from Solana to the destination chain by burning/locking the asset on Solana and sequentially minting on the destination chain. Solvers rebalance their inventory on Solana using these interoperable token standards as well. Once the originating source chain transaction reaches finality and arrives to Solana, the solver can redeem the NTT or CCTP message, minting the inventory for use once again. - -By leveraging interoperable token standards like NTT, this model of liquidity facilitation for cross-chain intents can arbitrarily scale to any chain or ecosystem while preserving fully unified liquidity. This removes the need for solver "buy-in" when expanding to new chains. Additionally, regardless of proven traction, new chains can access the same level of liquidity for cross-chain intent fulfillment from the first day of mainnet launch as long-standing ecosystems with clear evidence of adoption. This is often overlooked by solvers, who must aggressively prioritize high-flow chains due to high opportunity costs. The model also supports ecosystems without Centralized Exchange (CEX) enabled withdrawals. - -### Protocol Flow: How It Works - -1. **Initiation** - users or protocols initiate a transfer via an interface or directly on-chain. They choose between a standard transfer (waiting for finality on the sending chain) or a fast transfer (triggering the auction process). For fast transfers, users or the protocol specify a maximum fee and an auction start deadline - - !!! Note - If an auction doesn't start within the set deadline, a standard transfer will proceed directly from the source to the destination chain. - -2. **Auction** - solvers monitor the Wormhole network for these fast transfer requests and initiate an auction on Solana by offering to fulfill the transfer at or below the user's maximum fee. To start the auction, the solver must transfer the requested funds plus a small security deposit to the Matching Engine contract -3. **Competition** - once initiated, other solvers can participate by submitting lower bids in a simple English auction, aiming to provide users with the best rate. If a new solver submits a better offer, the previous solver's funds and security deposit are returned, with the latest offer taking precedence atomically. This competition ensures that users receive the best possible transfer rate -4. **Fulfillment** - after the auction concludes, the winning solver must complete the transfer within a predefined grace period to earn their fee and reclaim their security deposit. Failure to do so may result in the security deposit being slashed, with the slashed amount compensating the user for delays. This mechanism incentivizes prompt execution. Upon successful completion, the Fast Transfer hub sends the USDC to the user's destination wallet, and the solver receives their security deposit and transfer fee -5. **Settlement** - once the source chain transaction reaches finality, the winning solver can use the finalized Wormhole message to settle the auction with the matching engine and rebalance. This allows the solver to retrieve the original transfer amount into their wallet - -## Mayan Swift - -Mayan Swift is a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent. - -### On-Chain Competitive Price Discovery Mechanism - -Traditional intent-based protocols essentially function as cross-chain limit orders. If the order is profitable, solvers will compete to fulfill it, leading to MEV-like competition focused on speed. While functional, this methodology presents two clear inefficiencies and drawbacks. - -First, they lack a competitive price discovery mechanism as limit order prices are typically determined through centralized off-chain systems. Second, in this MEV-like market structure, only a single solver can win, while the others lose out on transaction fees. This dynamic of deadweight loss results in solvers prioritizing high-margin orders, ultimately resulting in elevated fees for end-users without commensurate benefits. - -Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. - -![Mayan Swift - Intent-centric design](/docs/images/learn/transfers/settlement/architecture/architecture-2.webp) - -### Protocol Flow: How It Works - -1. **Initiation** - the user creates an order by signing a transaction that locks one of the primary assets (USDC or ETH) into the Mayan smart contract, specifying the desired outcome. - - !!!note - If the input asset is not a primary asset, it is converted into a primary asset within the same transaction before the order is submitted. - - Each order includes properties such as destination chain, destination wallet address, output token address, minimum output amount, gas drop amount, deadline, and 32 bytes of random hex to prevent collisions. A Keccak-256 hash is then calculated to identify the order - -2. **Auction** - solvers observe on-chain data or subscribe to the Mayan explorer web socket (solvers using the Mayan explorer verify the order's integrity by checking the data against the on-chain hash). Once the new order is verified, an on-chain auction on Solana is initiated by passing the order ID and the bid amount, which cannot be lower than the minimum amount. Other solvers can increase the bid by submitting a higher amount before the auction ends -3. **Fulfillment** - the auction ends three seconds after the initial bid. Once the auction ends, the winning solver can execute an instruction that passes their wallet address on the destination chain. This triggers a Wormhole message containing the order ID and the winner's wallet address. Wormhole Guardians then sign this message, allowing the winning solver to fulfill the order on the destination chain by submitting proof of their win and the promised amount to the Mayan contract before the deadline. The Mayan contract deducts a protocol fee (currently 3 basis points) and a referral fee (if applicable), transferring the remaining amount to the user's destination wallet. It also triggers a Wormhole message as proof of fulfillment -4. **Settlement** - after the Wormhole Guardians sign the fulfillment message, the winning solver can submit this message on the source chain to unlock the user's funds and transfer them to their own wallet. Upon fulfillment, the solver has the option to delay triggering a Wormhole message immediately. Instead, they can batch the proofs and, once the batch reaches a certain threshold, issue a batched proof to unlock all orders simultaneously, saving on gas fees - -## Mayan MCTP - -Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. - -![Mayan MCTP diagram](/docs/images/learn/transfers/settlement/architecture/architecture-3.webp) - -### Protocol Flow: How It Works - -1. **Initiation** - the user creates an order by signing a transaction that locks one USDC into the Mayan smart contract, specifying the desired outcome. - - !!!note - If the input asset is not USDC, it is converted into a primary asset within the same transaction before the order is submitted. - - The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash - -2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} -3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules - -The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. - -## Where to Go Next - -- To learn more about available EVM functions, see the [Build on the Wormhole Liquidity Layer](/docs/build/transfers/settlement/liquidity-layer/){target=\_blank} guide -- To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/overview/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement Overview -description: Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. -categories: Settlement, Transfer ---- - -# Wormhole Settlement Overview - -## Introduction - -Wormhole Settlement is a fast, institutional-scale digital asset settlement — a new way to transfer assets across chains. - -With Wormhole Settlement, an intent-based asset transfer for individual users and institutions, you can swap, bridge, and build across multiple chains. You can implement cross-chain functionality within your dApps extremely simply and without compromising user experience, widening the horizons of your product offerings and the number and type of users you can cater to. - -The Settlement supports Ethereum, Ton, Optimism, Arbitrum, Base, Avalanche, Unichain, Polygon, Solana, and Sui, with many more on the horizon. It is powered by Wormhole Messaging, Wormhole Native Token Transfer (NTT), and Circle's CCTP and built in collaboration with the intent experts at Mayan Finance. - -Settlement represents Wormhole's first step towards optimizing the bridging experience and building a product that users and institutions use daily. Use it to send assets between chains, rebalance institutional inventories on-chain cheaply and quickly, or allow your application to be accessible by any user no matter what assets they hold or what chain they call home. - -## Key Features - -- **Integrator flexibility** - apps leveraging the SDK can select any one of three potential routes surfaced, each with its tradeoffs concerning time vs cost; they may extend this to users as well -- **Scalable liquidity** - taking into account the sometimes idiosyncratic yet sharp inflows into the Solana ecosystem, the hub-spoke model of the Wormhole Liquidity Layer and the flexible design of Swift are designed for capital efficiency -- **Arbitrary payload support** - integrators can bundle `callData` containing arbitrary protocol actions to enable seamless one-click user experiences, such as swap plus stake - -## Integrator Paths - -### SDK Integrators - -Wormhole provides an SDK that enables apps to abstract away the complexity of cross-chain token swaps. The SDK handles route discovery, fee estimation, and transaction construction. Apps can embed this feature in their backend or create an interface for users to bridge into their respective ecosystems quickly. - -### NTT Integrators - -NTT partners, current and future, can leverage Wormhole Settlement for near-instant NTT transfers from any chain, including Ethereum mainnet and its L2s. This eliminates waiting for slow source chain confirmation times (sometimes 15 minutes or more). If interested, please [fill out this interest form](https://wormhole.com/contact){target=\_blank}. - -### Chain Integrators - -Due to the hub-spoke model of liquidity, new chains without proven traction can access the same level of liquidity for cross-chain intent fulfillment from day one of mainnet launch as established ecosystems with clear evidence of adoption. - -!!!tip - Looking to integrate Wormhole Settlement? If you're ready, check out how to [integrate Wormhole Settlement Routes using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank}. - -## Related Resources - -- To learn more about the architecture of Wormhole-native swap protocols, see the [Settlement Protocol Architectures](/docs/learn/transfers/settlement/architecture/){target=\_blank} page ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/token-bridge/ ---- BEGIN CONTENT --- ---- -title: Token Bridge -description: Learn about Wormhole's Token Bridge for cross-chain transfers using lock and mint mechanisms, ensuring secure and efficient asset movement. -categories: Token-Bridge, Transfer ---- - -# Token Bridge - -Transferring tokens across blockchain networks is challenging due to the lack of interoperability. Maintaining token properties such as value, name, and precision while ensuring security during transfers often requires complex and costly solutions like liquidity pools or native swaps, which can introduce inefficiencies and risks. - -Wormhole’s Token Bridge addresses these challenges by providing a decentralized protocol for seamless cross-chain token transfers through a lock-and-mint mechanism. Using Wormhole’s message-passing protocol, the Token Bridge allows standards-compliant tokens, like ERC-20 on Ethereum or SPL on Solana, to be transferred between different blockchains while preserving their original attributes. - -Offering a more efficient, scalable, and secure alternative to traditional solutions, the Token Bridge ensures that assets retain their properties across multiple blockchain ecosystems. Additionally, it supports flexible features like [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, enabling custom interactions by allowing tokens to carry additional data for smart contract integration on the destination chain. - -This page introduces the core concepts and functions of Wormhole’s Token Bridge, explaining how it operates, its key features, and how it enables secure and efficient cross-chain token transfers. - -### How Does It Work? - -At the core of the Token Bridge lies the lock-and-mint mechanism, which uses the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} with a specific [payload](/docs/learn/infrastructure/vaas/#token-transfer){target=\_blank} to pass information about the transfer. Tokens on the source chain are locked, and wrapped tokens are minted on the destination chain. This approach guarantees that token transfers are secure and consistent, ensuring that token properties such as name, symbol, and decimal precision are preserved across chains. - -Before a token can be transferred to a new chain, the token’s metadata must be [attested](/docs/learn/infrastructure/vaas/#attestation){target=\_blank}. This process registers the token details (such as decimals and symbol) on the destination chain, enabling the creation of wrapped assets. - -While the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} has no specific receiver by default, transfers sent through the Token Bridge do have a specific receiver chain and address to ensure the tokens are minted to the expected recipient. - -In addition to standard token transfers, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}. This functionality allows users to attach additional data to token transfers, enabling more complex interactions with smart contracts on the destination chain. For instance, a token transfer can include a payload that triggers specific actions, such as interacting with a decentralized exchange (DEX) or automated market maker (AMM). - -### Token Transfer Flow - -The transfer process is simple yet secure, involving a few key steps: - -1. **Attestation** - first, a token's metadata is attested on the source chain, ensuring that its properties are consistent across chains -2. **Locking** - on the source chain, the native token is locked in a custody account -3. **Message emission** - a message detailing the transfer is sent through Wormhole’s Guardian Network, which verifies the transfer and signs the message -4. **Verification and minting** - on the destination chain, the transfer message is verified, and wrapped tokens are minted, or native tokens are released from custody - -![Token Bridge detailed flow](/docs/images/learn/transfers/token-bridge/token-bridge-diagram.webp) - -### Key Features of the Token Bridge - -The Token Bridge creates wrapped versions when tokens are transferred to a different chain. These wrapped assets represent the locked tokens on the source chain and allow users to interact with them on the destination chain. This mechanism ensures seamless functionality without needing liquidity pools or native token swaps. - -The Token Bridge employs a universal token representation that is compatible with various virtual machine (VM) data types. This allows the tokens to interact with decentralized applications (dApps) across different chains without issues related to differing token standards. - -### Message and Payload Structure - -To facilitate cross-chain communication, the Token Bridge uses specialized payloads that carry the necessary information for token transfers and attestations. These payloads ensure that the correct tokens are minted or unlocked on the destination chain. - -- `Transfer` - this payload initiates the transfer of tokens, either by minting wrapped tokens or releasing locked tokens -- `TransferWithPayload` - in addition to transferring tokens, this payload carries additional data, allowing integration with smart contracts or dApps on the target chain -- `AssetMeta` - before a token can be transferred for the first time, this payload is used to attest to the token’s metadata, including decimals, symbol, and name -- `RegisterChain` - register the Token Bridge contract (emitter address) for a foreign chain -- `UpgradeContract` - upgrade the contract - -Each payload type is designed to serve a specific function in the token transfer process, ensuring that the bridge operates efficiently and securely. - -One of the key challenges in cross-chain token transfers is maintaining the correct token precision. The Token Bridge addresses this using the `AssetMeta` payload to store token metadata. Before transferring a token to a new chain, metadata such as its decimal precision, name, and symbol must be attested. The bridge ensures token amounts are truncated to a maximum of 8 decimals, guaranteeing compatibility with chains that may not support higher decimal precision. For example, an 18-decimal token on Ethereum will be represented with only eight decimals on the destination chain, simplifying integration with various decentralized applications. - -### Security and Authorization - -The Token Bridge uses an emitter chain and address authorization system to verify the validity of messages. Each Token Bridge endpoint is registered on its respective chain, ensuring only trusted contracts can send or receive transfer messages. - -The [Wormhole Guardian Network](/docs/learn/infrastructure/guardians/#guardian-network){target=\_blank} plays a critical role in verifying each transfer and ensuring that the message is signed and relayed securely between chains. - -### Portal Bridge - -A real-world example of Wormhole's Token Bridge in action is the [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides users with a simple interface to transfer tokens across multiple blockchains. Using the Wormhole infrastructure, Portal Bridge guarantees secure and seamless cross-chain transfers, making it easier for users to move assets between different blockchain ecosystems. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- - -# Products - -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. - -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. - -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. - -## Transfer Products - -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. - -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods - -
- -::spantable:: - -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - -::end-spantable:: - -
- -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - -## Bridging UI - -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - -## Real-time Data - -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. - -## Multichain Governance - -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/cctp/ ---- BEGIN CONTENT --- ---- -title: Interacting with CCTP Contracts -description: Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. -categories: Transfer ---- - -# Get Started with CCTP - -## Introduction - -Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/learn/transfers/cctp/){target=\_blank} by Circle is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. - -As decentralized finance (DeFi) protocols evolve, the need for flexible, secure cross-chain messaging has expanded, requiring solutions beyond simple asset transfers. Wormhole enhances CCTP's capabilities by allowing developers to compose more complex cross-chain interactions. With Wormhole's generic messaging, applications can execute smart contract logic alongside native USDC transfers, enabling richer, more versatile cross-chain experiences. - -This guide will walk you through getting started with Wormhole's CCTP contracts and show you how to integrate CCTP into your smart contracts, enabling the composition of advanced cross-chain functions with native USDC transfers. - -## Prerequisites - -To interact with the Wormhole CCTP, you'll need the following: - -- [The address of the CCTP contract](/docs/build/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on - -## Wormhole's CCTP Integration Contract - -Wormhole's Circle Integration contract, `CircleIntegration.sol`, is the contract you'll interact with directly. It burns and mints Circle-supported tokens by using [Circle's CCTP contracts](#circles-cctp-contracts). - -The Circle Integration contract emits Wormhole messages with arbitrary payloads to allow additional composability when performing cross-chain transfers of Circle-supported assets. - -This contract can be found in [Wormhole's `wormhole-circle-integration` repository](https://github.com/wormhole-foundation/wormhole-circle-integration/){target=\_blank} on GitHub. - -!!! note - Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/build/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. - -??? code "Circle Integration contract" - ```solidity - // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.19; - -import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {IWormhole} from "wormhole/interfaces/IWormhole.sol"; -import {BytesLib} from "wormhole/libraries/external/BytesLib.sol"; - -import {ICircleBridge} from "../interfaces/circle/ICircleBridge.sol"; - -import {CircleIntegrationGovernance} from "./CircleIntegrationGovernance.sol"; -import {CircleIntegrationMessages} from "./CircleIntegrationMessages.sol"; +import {CircleIntegrationGovernance} from "./CircleIntegrationGovernance.sol"; +import {CircleIntegrationMessages} from "./CircleIntegrationMessages.sol"; /** * @notice This contract burns and mints Circle-supported tokens by using Circle's Cross-Chain Transfer Protocol. It also emits @@ -954,7 +568,7 @@ contract CircleIntegration is // Call the circle bridge and `depositForBurnWithCaller`. The `mintRecipient` // should be the target contract (or wallet) composing on this contract. - (uint64 nonce, uint256 amountReceived) = _transferTokens( + (uint64 nonce, uint256 amountReceived) = _transferTokens{value: wormholeFee}( transferParams.token, transferParams.amount, transferParams.targetChain, @@ -3469,117 +3083,171 @@ function receivePayloadAndUSDC( To view a complete example of creating a contract that integrates with Wormhole's CCTP contracts to send and receive USDC cross-chain, check out the [Hello USDC](https://github.com/wormhole-foundation/hello-usdc){target=\_blank} repository on GitHub. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/ +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/overview/ --- BEGIN CONTENT --- --- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate multichain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer +title: CCTP Bridge with Wormhole +description: Learn how the integration of Circle's CCTP with Wormhole enables secure and efficient native USDC transfers and complex cross-chain interactions. +categories: Transfer --- -# Wormhole Connect +# CCTP with Wormhole Overview + +The integration of [Circle's Cross-Chain Transfer Protocol (CCTP)](https://www.circle.com/cross-chain-transfer-protocol){target=\_blank} with the Wormhole messaging protocol creates a robust system for securely and efficiently transferring native USDC across different blockchain networks while enabling more complex multichain interactions. This combination streamlines the movement of stablecoins, reduces risk, and unlocks new possibilities for decentralized applications. + +## Key Features + +- **Secure native USDC transfers**: At its core, CCTP provides a "burn-and-mint" mechanism for transferring native USDC. This eliminates the need for wrapped assets and the associated risks of intermediary bridges. +- **Atomic execution**: By combining CCTP and Wormhole, the transfer of USDC and the execution of accompanying instructions on the destination chain can occur as a single atomic transaction. +- **Automated relaying**: Eliminates the need for users to redeem USDC transfers themselves. +- **Enhanced composability**: Developers can build more sophisticated cross-chain applications by sending additional data alongside the transfer. +- **Gas drop off**: Enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer. +- **Gas payment**: Covering destination gas in automated vs. manual transfers. + - **Automated**: Users often don't need destination gas tokens upfront, relayers cover these gas costs, reimbursed via gas drop-off or initial fees. + - **Manual**: Users pay destination gas directly, the protocol may offer post-claim USDC-to-gas conversion. + +## How It Works + +This section outlines the end-to-end flow for transferring native USDC across chains using CCTP while optionally triggering an action on the destination chain. Circle and Wormhole coordinate each step to ensure a secure, verifiable transfer and execution process. + +1. **Alice initiates a transfer on Ethereum**: She submits a request to the Circle Bridge to send 100 USDC to Avalanche. If desired, she could include optional payload data. + +2. **Tokens are taken into custody and burned**: The Circle Bridge takes custody of Alice's USDC and initiates a burn using Circle's CCTP, triggering an off-chain attestation process. + +3. **A Wormhole message is published**: The transfer metadata is emitted as a Wormhole message. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate and sign it to produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. + +4. **A relayer automatically processes the messages**: Once the VAA and Circle attestation are available, a relayer submits them to the Circle Bridge on Avalanche. -Wormhole Connect is a customizable widget that brings wrapped and native token cross-chain asset transfers into your dApp in as few as 3 lines of code. Connect is available as a React component or hosted version via CDN so you can easily configure any application to transfer tokens via Wormhole. +5. **Tokens are minted**: The Circle Bridge verifies both proofs and mints 100 USDC to Alice using Circle's CCTP. If a payload is included, it can be executed atomically. -## Build with Connect +```mermaid +sequenceDiagram + participant User as Alice + participant SourceChain as Circle Bridge
on Ethereum + participant Circle + participant Guardians as Wormhole Guardians + participant Relayer + participant DestinationChain as Circle Bridge
on Avalanche -[timeline left(wormhole-docs/.snippets/text/build/transfers/connect/connect-timeline.json)] + User->>SourceChain: Submit transfer
(100 USDC to Avalanche) + SourceChain->>Circle: Initiate a burn + Circle->>Circle: Burn USDC and provide attestation + SourceChain->>Guardians: Emit Wormhole message (transfer metadata) + Guardians->>Guardians: Sign message and produce VAA + Relayer->>Guardians: Fetch signed VAA + Relayer->>Circle: Fetch Circle burn attestation + Relayer->>DestinationChain: Submit VAA and
attestation + DestinationChain->>Circle: Verify Circle attestation + Circle->>User: Mint USDC to Alice +``` + +!!! note + For a cross-chain transfer to be successful, both the source and destination chains must be among those supported by [Circle's CCTP](https://developers.circle.com/stablecoins/supported-domains){target=\_blank}. -## See It In Action +## Use Cases -Wormhole Connect is deployed live in several production apps. Here are a few: +Integrating Wormhole's messaging with CCTP enables the secure transfer of native USDC across blockchains, unlocking key cross-chain use cases, which include: -- [Portal Bridge](https://portalbridge.com/){target=\_blank} -- [Jupiter](https://jup.ag/onboard/cctp){target=\_blank} -- [Pancake Swap](https://bridge.pancakeswap.finance/wormhole){target=\_blank} +- **USDC Payments Across Chains** + - [**CCTP**](/docs/products/cctp-bridge/get-started/): Transfer native USDC using Circle’s burn-and-mint protocol. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Automate attestation delivery and gas handling. + - [**Connect**](/docs/products/connect/overview/): Embed multichain USDC transfers directly in your app. -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} page to learn how to combine Connect with other Wormhole products, including Native Token Transfer (NTT). +- **USDC-Powered Multichain Settlement** + - [**Settlement**](/docs/products/settlement/overview/): Use the Liquidity Layer to settle intents with native USDC. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Initiate transfers, discover routes, and execute swaps seamlessly. ## Next Steps -
+Now that you're familiar with CCTP, here is a list of resources for more hands-on practice: -- :octicons-tools-16:{ .lg .middle} **Get Started Now** +- [**Get started with CCTP Bridge**](/docs/products/cctp-bridge/get-started/): Perform a multichain USDC transfer from Avalanche to Sepolia using Wormhole's TypeScript SDK and Circle's CCTP. +- [**Complete USDC Transfer Flow**](/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/): Execute a USDC cross-chain transfer using Wormhole SDK and Circle's CCTP, covering manual, automatic, and partial transfer recovery. +- [**Checkout Circle's CCTP Docs**](https://developers.circle.com/stablecoins/cctp-getting-started){target=\_blank}: Learn more about Circle's cross-chain transfer protocol in their documentation. +--- END CONTENT --- - --- +Doc-Content: https://wormhole.com/docs/products/connect/concepts/routes/ +--- BEGIN CONTENT --- +--- +title: Routes +description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. +categories: Connect, Transfer +--- - Follow this series of how-to guides to integrate Connect into your React dApp and configure options to fit your user's needs. +## Routes Overview {: #routes-overview} - [:custom-arrow: Get started](/docs/build/transfers/connect/overview/#integrate-connect) +This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/products/connect/configuration/data/){target=\_blank}. -- :octicons-tools-16:{ .lg .middle } **Multichain Swap** +Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. - --- +When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/products/connect/reference/support-matrix/){target=\_blank} to see under which exact conditions the routes appear. - This tutorial guides you step-by-step through integrating Connect into your React dApp to transfer tokens from Sui to Avalanche Fuji. This tutorial is readily adaptable to work with other [supported networks](/docs/build/start-building/supported-networks/){target=\_blank}. +## Token Bridge Routes {: #token-bridge-routes} +The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. - [:custom-arrow: Get started](/docs/tutorials/connect/react-dapp/) +#### Manual Route {: #manual-route} +The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. -- :octicons-tools-16:{ .lg .middle } **Connect FAQs** +#### Automatic Route {: #automatic-route} - --- +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. - Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. +## CCTP Routes (USDC) {: #cctp-routes-usdc} + +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. - [:custom-arrow: Visit FAQs](/docs/build/transfers/connect/faqs/) +Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. -- :octicons-tools-16:{ .lg .middle } **Supported Features by Chain** +#### Manual Route {: #manual-route-cctp} - --- +This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. - Get a more detailed look at Wormhole Connect features with a breakdown of supported features by chain. +#### Automatic Route {: #automatic-route-cctp} - [:custom-arrow: Supported Features](/docs/build/transfers/connect/features/) +Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. -
---- END CONTENT --- +## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer ---- +[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/products/connect/configuration/data/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. -# Wormhole Connect +#### Manual Route {: #manual-route-ntt} -## Configure Connect +This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. -Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. +#### Automatic Route {: #automatic-route-ntt} -This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. -!!! note - To upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for instructions. +## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} - If you're using an older version of Wormhole Connect (v0.x), please refer to the [v0.x configuration documentation](/docs/build/transfers/connect/configuration-v0/){target=\_blank}. +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). -
+#### Automatic Route {: #automatic-route-eth} -- :octicons-database-16:{ .lg .middle } **Data** +Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. - --- +## USDT Bridge Route {: #usdt-bridge-route} - Learn how to configure the networks, tokens, and routes supported by Wormhole Connect. Set up RPC endpoints, whitelist tokens, and leverage multiple bridging protocols to meet your dApp's needs. +Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. +#### Automatic Route {: #automatic-route-usdt} - [:custom-arrow: Get started](/docs/build/transfers/connect/configuration/configure-data/) +Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. -- :octicons-apps-16:{ .lg .middle } **Theme** +## tBTC Route {: #tbtc-route} - --- +You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). - Discover how to style the Wormhole Connect widget to align with your brand. Customize colors, fonts, and UI elements to deliver a seamless user experience. +Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. - [:custom-arrow: Explore routes](/docs/build/transfers/connect/configuration/configure-theme/) +#### Manual Route {: #manual-route-tbtc} -
+This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-data/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/data/ --- BEGIN CONTENT --- --- title: Connect Data Configuration @@ -3700,18 +3368,18 @@ By default, Connect offers two bridging protocols: Token Bridge (for Wormhole-wr The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: -- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank} - manually redeemed Wormhole Token Bridge route -- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank} - automatically redeemed (relayed) Token Bridge route -- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank} - manually redeemed CCTP route -- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank} - automatically redeemed (relayed) CCTP route -- **`DEFAULT_ROUTES`** - array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`) -- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank} - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route -- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}- function that returns the manually-redeemed NTT route -- **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array -- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank} - route that offers multiple Mayan protocols -- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank} - route for Mayan's Swift protocol only -- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank} - route for Mayan's MCTP protocol only -- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank} - route for Mayan's original Wormhole transfer protocol +- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank}: Manually redeemed Wormhole Token Bridge route. +- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank}: Automatically redeemed (relayed) Token Bridge route. +- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank}: Manually redeemed CCTP route. +- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank}: Automatically redeemed (relayed) CCTP route. +- **`DEFAULT_ROUTES`**: Array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`). +- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank}: Function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route. +- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}: Function that returns the manually-redeemed NTT route. +- **`nttRoutes(nttConfig)`**: Function that returns both NTT routes as an array. +- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank}: Route that offers multiple Mayan protocols. +- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank}: Route for Mayan's Swift protocol only. +- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank}: Route for Mayan's MCTP protocol only. +- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank}: Route for Mayan's original Wormhole transfer protocol. In addition to these routes, developers can create custom routes for their Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. @@ -3736,7 +3404,7 @@ const config: WormholeConnectConfig = { #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript import WormholeConnect, { @@ -3942,27 +3610,9 @@ Your selected blockchain network determines the available wallet options when us The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. - -### CoinGecko API Key {: #coingecko-api-key } - -The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. - -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; - -const config: WormholeConnectConfig = { - coinGeckoApiKey: 'INSERT_API_KEY', -}; - -function App() { - return ; -} -``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-theme/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/theme/ --- BEGIN CONTENT --- --- title: Connect Theme & UI Customization @@ -3972,7 +3622,7 @@ categories: Connect, Transfer ## Theme & UI Customization -This page focuses on how to style the Wormhole Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. +This page focuses on how to style the Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. ### Changing the Color Scheme @@ -4082,7 +3732,7 @@ function App() { ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/faqs/ +Doc-Content: https://wormhole.com/docs/products/connect/faqs/ --- BEGIN CONTENT --- --- title: Connect FAQs @@ -4094,7 +3744,7 @@ categories: Connect, Transfer ## What types of assets does Connect support? -Wormhole Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: +Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: - Major stablecoins like USDT and USDC (via CCTP) - Native gas tokens such as ETH, SOL, etc. @@ -4110,7 +3760,7 @@ Connect supports around 30 chains, spanning various blockchain runtimes: - Solana - Move-based chains (Sui, Aptos) -For a complete list of supported chains, see the [Connect-supported chains list](/docs/build/transfers/connect/features/){target=\_blank}. +For a complete list of supported chains, see the [Connect-supported chains list](/docs/products/connect/reference/support-matrix/){target=\_blank}. ## What is gas dropoff? @@ -4124,9 +3774,9 @@ Connect can be [fully customized](https://connect-in-style.wormhole.com/){target Connect relies on the NTT SDK for integration, with platform-specific implementations for Solana and EVM. The critical methods involved include initiate and redeem functions and rate capacity methods. These functions ensure Connect can handle token transfers and manage chain-rate limits. -## Do integrators need to enable wallets like Phantom or Backpack in Wormhole Connect? +## Do integrators need to enable wallets like Phantom or Backpack in Connect? -Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Wormhole Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. +Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. ## Which function should be modified to set priority fees for Solana transactions? @@ -4156,276 +3806,201 @@ Additional notes: The TypeScript SDK was previously referred to as the "Connect SDK," but this naming has since been discontinued. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/features/ ---- BEGIN CONTENT --- ---- -title: Features -description: Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. -categories: Connect, Transfer ---- - -## Feature Support Matrix {: #feature-support-matrix} - -*Scroll down for details about each column.* - -| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | -|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| -| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | -| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | -| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | -| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | -| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | -| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | -| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | -| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | -| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | -| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | -| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | -| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | -| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | -| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | -| Base | ✅ | ✅ | ✅ | ✅ | ✅ | -| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | -| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | -| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | -| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | - -## Feature Explanation {: #feature-explanation} - -### Token Bridge {: #token-bridge} - -Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. - -This route appears if both of the following conditions are satisfied: - - - Both the origin and destination chains support Token Bridge - - No non-Token Bridge routes are available for the selected token - -### Token Bridge Relayer {: #token-bridge-relayer} - -On the [routes](/docs/build/transfers/connect/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. - -Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. - -This route appears if all of the following conditions are satisfied: - -- Both the origin and destination chains support Token Bridge -- Both the origin and destination chains support Token Bridge relayer -- No non-Token Bridge routes are available for the selected token -- The relayer supports the selected token on the origin chain - -### Circle CCTP {: #circle-cctp} - -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. - -This route appears if all of the following conditions are satisfied: - -- Both the origin and destination chains support Circle CCTP -- The selected token is native Circle-issued USDC - -### ETH Bridge {: #eth-bridge} - -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. - -This route appears if all of the following conditions are satisfied: - -- Both the origin and destination chains support the ETH Bridge -- The selected token is native ETH, wstETH, or canonical wETH - -### Gas Drop Off {: #gas-drop-off} - -A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. - -This route appears if all of the following conditions are satisfied: - -- Both the origin and destination chains support gas drop off -- An automatic route is selected -- The relayer accepts the selected token to swap into the gas token ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/connect/overview/ +Doc-Content: https://wormhole.com/docs/products/connect/get-started/ --- BEGIN CONTENT --- --- -title: Overview -description: Explore Wormhole Connect, the React widget that allows you to offer an easy-to-use UI for cross-chain asset transfers via Wormhole in a web application. +title: Get Started with Connect +description: Follow this guide to configure and use the Connect UI widget to easily add an intuitive, multichain asset transfer UI to your web applications. categories: Connect, Transfer --- -# Wormhole Connect +# Get Started with Connect -## Introduction {: #introduction } - -Wormhole Connect is a React widget that lets developers offer an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. Check out the [Wormhole Connect GitHub repository](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. - -The [Wormhole TypeScript SDK](https://docs.wormhole.com/wormhole/reference/sdk-docs){target=\_blank} allows you to implement the same functionality as the Connect widget but in your own UI. Check out the docs for more information on using the SDK instead of Connect. - -## Features {: #features } - -Wormhole Connect is easy to customize to suit your application's needs. You can specify technical details like supported assets and custom RPCs or forgo customization and have a full-featured widget. The widget UI is highly customizable, with extensive styling options available, including a user-friendly no code styling interface for those who prefer a more visual approach to design. The features of Wormhole Connect include: - -- Multiple ways to bridge assets ([routes](/docs/build/transfers/connect/routes/){target=\_blank}) -- Extensive ways to style the UI (including the [no code styling interface](https://connect-in-style.wormhole.com/){target=\_blank}) -- Ways to [configure](/docs/build/transfers/connect/configuration/){target=\_blank} what feature set to offer -- Ability to configure any token to bridge via Wormhole -- [Ability to drop off some gas](/docs/build/transfers/connect/features/){target=\_blank} at the destination +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -For more details about the features of Wormhole Connect and a breakdown of supported features by chain, be sure to check [the features page](/docs/build/transfers/connect/features/){target=\_blank}. +## Introduction -## Integrate Connect {: #integrate-connect } +Connect helps you to easily add an intuitive, multichain asset transfer UI to your web applications. The guide demonstrates how to configure the Connect widget, add it to a React application, and view it locally. -### Import Directly into a React App {: #import-directly-into-a-react-app} +## Install Connect -First, install the Wormhole Connect npm package. You can read more about the package by clicking on the following button: [![npm version](https://img.shields.io/npm/v/@wormhole-foundation/wormhole-connect.svg)](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} +To install the [Wormhole Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: ```bash npm i @wormhole-foundation/wormhole-connect ``` -Now you can import the React component: - -```ts -import WormholeConnect from '@wormhole-foundation/wormhole-connect'; - -function App() { - return ; -} -``` - -### Use Hosted Version via CDN {: #use-hosted-version-via-cdn} +## Prerequisites -If you're not using React, you can still embed Connect on your website by using the hosted version. This uses pre-built packages (which include React) served from NPM by jsdelivr.net. +Before you begin, make sure you have the following: -```ts title="v1.x" -import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} -// Existing DOM element where you want to mount Connect -const container = document.getElementById('bridge-container'); +- (Optional) To test a transfer from your demo app, you'll need: -wormholeConnectHosted(container); -``` + - A wallet with [Sui testnet tokens](https://faucet.sui.io/){target=\_blank} + - A wallet with an Avalanche Fuji address (to use as the recipient; no tokens required) -For help migrating from Connect v0.x to v1.x, see the [v1 Migration](/docs/build/transfers/connect/upgrade/){target=\_blank} guide. +## Install and Set Up Project -???- code "v0.x" - Simply copy and paste the following into your HTML body, and replace the ```INSERT_WORMHOLE_CONNECT_VERSION``` in the links with the most recent production version of Wormhole Connect. You can check what the most recent version is on [NPM](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/latest){target=\_blank}. +1. Clone the demo repository and navigate to the project directory: - ```html - -
- - - + ```bash + git clone https://github.com/wormhole-foundation/demo-basic-connect.git + cd demo-basic-connect ``` - For example, for [0.3.13](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/0.3.13){target=\_blank}: +2. Install the dependencies: - ```html - -
- - - + ```bash + npm install ``` -It is important to periodically update your Wormhole Connect instance to the latest version, as there are frequent functionality and security releases. - -## Configuration {: #configuration} +3. Start the application: -This is just an overview of what's possible. Check the [Configuration docs](/docs/build/transfers/connect/configuration/){target=\_blank} for details about all the configuration options. - -The default configuration of Wormhole Connect may not be exactly what you're looking for. You may want to: - - - Use custom styles - - Restrict the chains that you allow in your app - - Add support for your project's token, and eliminate tokens you don't want to reduce noise - - Configuring custom RPC URLs (This is highly recommended as default public RPCs are heavily throttled) - - Restrict the [routes](/docs/build/transfers/connect/routes/){target=\_blank} that are available + ```bash + npm start + ``` -For additional information on the preceding options, check the [configuration options](/docs/build/transfers/connect/configuration/){target=\_blank} and customize your widget however you like. ---- END CONTENT --- +4. Open your browser to [localhost:3000](http://localhost:3000){target=\_blank} to view the application locally. It will look similar to the following: -Doc-Content: https://wormhole.com/docs/build/transfers/connect/routes/ ---- BEGIN CONTENT --- ---- -title: Routes -description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. -categories: Connect, Transfer ---- + ![Deployed Connect Widget](/docs/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp) -## Routes Overview {: #routes-overview} +## Configure Connect -This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/build/transfers/connect/configuration/){target=\_blank}. +Open the `App.tsx` file in your code editor of choice. You will see code similar to the following: -Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. +```typescript title="App.tsx" +import './App.css'; +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; -When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/build/transfers/connect/features/){target=\_blank} to see under which exact conditions the routes appear. +function App() { + const config: WormholeConnectConfig = { + // Define the network + network: 'Testnet', -## Token Bridge Routes {: #token-bridge-routes} + // Define the chains + chains: ['Sui', 'Avalanche'], -The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. + // UI configuration + ui: { + title: 'SUI Connect TS Demo', + }, + }; -#### Manual Route {: #manual-route} + const theme: WormholeConnectTheme = { + // Define the theme + mode: 'dark', + primary: '#78c4b6', + }; -The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. + return ; +} -#### Automatic Route {: #automatic-route} +export default App; +``` -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. +The preceding sample code configures Connect by setting values inside `config` and `theme` as follows: -## CCTP Routes (USDC) {: #cctp-routes-usdc} - -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. +- **Defines the network**: Options include `Mainnet`, `Testnet`, or `Devnet`. +- **Defines chains to include**: This example uses Sui and Avalanche. See the complete list of [Connect-supported chain names](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank} if you would like to use different chains. +- **Adds a title to UI**: (Optional) If defined, it will render above the widget in the UI. +- **Defines the theme**: This example sets the mode to `dark` and adds a primary color. -Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. +## Interact with Connect -#### Manual Route {: #manual-route-cctp} +Congratulations! You've successfully used Connect to create a simple multichain token transfer application. You can now follow the prompts in the UI to connect your developer wallets and send a test transfer. -This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. +## Next Steps -#### Automatic Route {: #automatic-route-cctp} +Use the following guides to configure your Connect instance and integrate it into your application: -Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. +- **[Integrate Connect into a React DApp](/docs/products/connect/tutorials/react-dapp/)**: Learn how to integrate Connect into a React application, including setting up the widget and handling transfers. -## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} + +--- END CONTENT --- -[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/build/transfers/connect/configuration/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. +Doc-Content: https://wormhole.com/docs/products/connect/guides/hosted-version/ +--- BEGIN CONTENT --- +--- +title: Integrate Connect via CDN +description: +categories: Connect, Transfer +--- -#### Manual Route {: #manual-route-ntt} +# Integrate Connect via CDN -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. +[Wormhole Connect](/docs/products/connect/overview/){target=\_blank} is a prebuilt UI component that makes it easy to transfer tokens across chains. You can integrate it into any website using either React or a hosted version served via [jsDelivr](https://www.jsdelivr.com/){target=\_blank}. -#### Automatic Route {: #automatic-route-ntt} +This guide focuses on using the hosted version—ideal for simpler setups or non-React environments. It includes everything you need to get started with just a few lines of code. -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. +If you're using React, refer to the [Get Started with Connect](/docs/products/connect/get-started/){target=\_blank} guide. -## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} +## Install Connect -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). +To install the [Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: -#### Automatic Route {: #automatic-route-eth} +```bash +npm i @wormhole-foundation/wormhole-connect +``` -Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. +## Add Connect to Your Project Using the Hosted Version -## USDT Bridge Route {: #usdt-bridge-route} +The hosted version uses pre-built packages (including React) served via jsDelivr from npm. To integrate it without using React directly, add the following to your JavaScript project: -Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. +```js +import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; -#### Automatic Route {: #automatic-route-usdt} +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'bridge-container' not found"); +} -Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. +wormholeConnectHosted(container); +``` -## tBTC Route {: #tbtc-route} +You can provide config and theme parameters in a second function argument: -You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). +```js +import { + wormholeConnectHosted, +} from '@wormhole-foundation/wormhole-connect'; -Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'connect' not found"); +} -#### Manual Route {: #manual-route-tbtc} +wormholeConnectHosted(container, { + config: { + rpcs: { + // ... + } + }, + theme: { + background: { + default: '#004547', + } + } +}); +``` -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. +## Next Steps + +Use the following guides to configure your Connect instance: + +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/upgrade/ +Doc-Content: https://wormhole.com/docs/products/connect/guides/upgrade/ --- BEGIN CONTENT --- --- title: Wormhole Connect v1.0 Migration Guide @@ -4447,11 +4022,9 @@ This guide will help you migrate to the new version in just a few simple steps. These updates ensure better performance and a smoother integration experience. -For complete documentation on the previous version of Wormhole Connect, please refer to the [Wormhole Connect guide](/docs/build/transfers/connect/){target=\_blank}. - ## Update the Connect Package -To begin the migration process, update the Wormhole Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. +To begin the migration process, update the Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. Run the following command in your terminal: @@ -4554,12 +4127,12 @@ The `networks` property, which allowed whitelisting chains, is now renamed `chai ### Update `routes` to Use Route Plugins -The `routes` property in Wormhole Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. +The `routes` property in Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. -By default, if no `routes` property is set, Wormhole Connect will provide routes for two core protocols: +By default, if no `routes` property is set, Connect will provide routes for two core protocols: - - [Wormhole Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} - - [CCTP](/docs/learn/transfers/cctp/){target=\_blank} + - [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} + - [CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} For most use cases, integrators require more than the default routes. The new `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including both default and third-party routes. @@ -4568,7 +4141,7 @@ For most use cases, integrators require more than the default routes. The new `r The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: ???- tip "`route` Plugins" - - **`TokenBridgeRoute`** - manually redeemed Wormhole Token Bridge route + - **`TokenBridgeRoute`** - manually redeemed Token Bridge route - **`AutomaticTokenBridgeRoute`** - automatically redeemed (relayed) Token Bridge route - **`CCTPRoute`** - manually redeemed CCTP route - **`AutomaticCCTPRoute`** - automatically redeemed (relayed) CCTP route @@ -4589,7 +4162,7 @@ Now that you know the available `route` plugins, let's explore some examples of #### Example: Offer Only CCTP Transfers -To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: +To configure Connect to offer only USDC transfers via the CCTP route, use the following configuration: ```typescript import WormholeConnect, { @@ -4606,7 +4179,7 @@ const config: WormholeConnectConfig = { #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript import WormholeConnect, { @@ -4629,7 +4202,7 @@ This flexible plugin allows you to combine default routes (such as Token Bridge ### Update the `tokensConfig` Structure -In Wormhole Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. +In Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. Key Changes to `tokensConfig`: @@ -4706,7 +4279,7 @@ Key Changes to `tokensConfig`: ### Update NTT Configuration -In Wormhole Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. +In Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. Key changes: @@ -4805,7 +4378,7 @@ This change simplifies the configuration process by providing a cleaner, more fl ### Update UI Configuration -In Wormhole Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. +In Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. Key UI changes: @@ -4929,7 +4502,7 @@ Important details: ### Removed Configuration Properties -Several configuration properties have been removed in Wormhole Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. +Several configuration properties have been removed in Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. Removed config keys: @@ -4957,7 +4530,7 @@ For those using the CDN-hosted version of Wormhole Connect, the package's instal npm install @wormhole-foundation/wormhole-connect@^1.0 ``` -2. After installing the package, you can embed Wormhole Connect into your page by adding the following code: +2. After installing the package, you can embed Connect into your page by adding the following code: ```typescript import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; @@ -4997,169 +4570,314 @@ wormholeConnectHosted(container, { In this example, the `config` object defines the routes (in this case, using the Mayan route), while the `theme` object allows customization of the Connect interface (e.g., background color). --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/ +Doc-Content: https://wormhole.com/docs/products/connect/overview/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) -description: This section provides comprehensive guidance on configuring, deploying, and managing your Native Token Transfers (NTT) integration. -categories: NTT, Transfer +title: Wormhole Connect +description: With Wormhole Connect, you can seamlessly bridge digital assets and data across a wide range of supported blockchain networks. +categories: Connect, Transfer --- -# Native Token Transfers +# Connect Overview -Native Token Transfers (NTT) simplifies and enables seamless, flexible token transfers across blockchains. This section provides comprehensive guidance on configuring, deploying, and managing your NTT integration. It includes information relevant to both new token deployments and existing token management. +With the Wormhole Connect widget, you can enable users to perform multichain asset transfers directly within your application. Connect simplifies the complexity of bridging, offering a single, intuitive point of interaction for moving assets across diverse blockchains. This empowers you to access liquidity and opportunities across any connected network seamlessly. -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} and [Product Comparison](/docs/build/start-building/products/){target=\_blank} pages for help determining if NTT will meet the needs of your project. +## Key Features -## Quickstart +Connect's notable features include: -If needed, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. +- **In-app multichain transfers**: Bridge assets without leaving your app. +- **Customizable features**: Specify chains and custom RPCs, manage tokens, and select bridging [routes](/docs/products/connect/concepts/routes/){target=\_blank} such as Token Bridge, CCTP, or NTT. +- **Customizable UI**: Style the bridge interface to match your brand. +- **Optional destination gas**: Provide gas for initial transactions on the target chain. +- **Wrapped and native assets support**: Supports both wrapped and native tokens and integrates with Settlement. -The process for creating, deploying, and monitoring NTTs is as follows. Select the title of each step to view the associated guide: +Be sure to check the [Feature Support Matrix](/docs/products/connect/reference/support-matrix/#feature-support-matrix){target=\_blank} to find out which routes and features are supported for each chain. -[timeline left(wormhole-docs/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json)] +## How It Works -## Deploy NTTs with Launchpad +When a user initiates a multichain transfer, Connect walks them through key steps and automates the transfer process behind the scenes, including: -If you are deploying to EVM blockchains, the [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT. NTT Launchpad replaces manually deploying contracts or configuring relayers for each supported EVM chain. +1. **Initiating the transfer**: Connect your chosen wallet to the source chain, select asset and source chain for the transfer. +2. **Finalize transfer setup**: Connect the destination wallet, select the target chain and select a bridging route (manual or automatic). +3. **Transaction submission on source chain**: Confirms the transfer details to trigger the asset lock or deposit on the initial blockchain. Connect will guide you through the transaction process. +4. **VAA or attestation creation**: Wormhole [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the source transaction and produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. +5. **Relaying to destination**: The VAA or attestation is automatically relayed to the destination chain. +6. **Verification on destination**: Contracts on the target chain receive and verify the incoming VAA. +7. **Asset release/minting**: Upon successful verification, the equivalent assets are either released or minted on the target chain and delivered to your wallet. -Follow the [Deploy NTT with Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/){target=\_blank} guide to create new multichain tokens or integrate existing tokens with just a few clicks. +!!! tip + If you want more hands on experience with Connect, checkout [Portal Bridge](https://portalbridge.com/){target=\_blank}. -## Additional Resources +## Use Cases -
+Here are some key use cases that highlight the power and versatility of Connect: -- :octicons-gear-16:{ .lg .middle } **NTT CLI Commands** +- **Cross-Chain Swaps and Liquidity Aggregation** - --- + - [**Connect**](/docs/products/connect/get-started/): Handles user-friendly asset transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Moves native assets across chains. + - [**Queries**](/docs/products/queries/overview/): Fetches real-time prices for optimal trade execution. - The NTT CLI tool provides a comprehensive set of commands for creating, configuring, deploying, and monitoring NTTs. This page provides a comprehensive list of available NTT CLI commands, their descriptions, and examples to help you interact effectively with the NTT system. +- **Cross-Chain Payment Widgets** - [:custom-arrow: NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/) + - [**Connect**](/docs/products/connect/get-started/): Facilitates seamless payments in various tokens. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Ensures direct, native asset transfers. -- :octicons-question-16:{ .lg .middle } **NTT FAQs** +- **Web3 Game Asset Transfers** - --- + - [**Connect**](/docs/products/connect/get-started/): Provide a user-friendly way to move game tokens across chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/): Handle the underlying lock-and-mint logic securely. - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +## Next Steps - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) +Add Connect to your app with these key setup steps: -
+[timeline(wormhole-docs/.snippets/text/products/connect/overview/connect-timeline.json)] --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/cli-commands/ +Doc-Content: https://wormhole.com/docs/products/connect/reference/support-matrix/ --- BEGIN CONTENT --- --- -title: NTT CLI Commands -description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. -categories: NTT, Transfer +title: Features +description: Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. +categories: Connect, Transfer --- -# NTT CLI Commands +## Feature Support Matrix {: #feature-support-matrix} + +*Scroll down for details about each column.* + +| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | +|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| +| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | +| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | +| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | +| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | +| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | +| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | +| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | +| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | +| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | +| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | +| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | +| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | +| Base | ✅ | ✅ | ✅ | ✅ | ✅ | +| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | +| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | +| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | +| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | + +## Feature Explanation {: #feature-explanation} + +### Token Bridge {: #token-bridge} + +Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. + +This route appears if both of the following conditions are satisfied: + + - Both the origin and destination chains support Token Bridge + - No non-Token Bridge routes are available for the selected token + +### Token Bridge Relayer {: #token-bridge-relayer} + +On the [routes](/docs/products/connect/concepts/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. + +Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. + +This route appears if all of the following conditions are satisfied: + +- Both the origin and destination chains support Token Bridge +- Both the origin and destination chains support Token Bridge relayer +- No non-Token Bridge routes are available for the selected token +- The relayer supports the selected token on the origin chain + +### Circle CCTP {: #circle-cctp} + +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. + +This route appears if all of the following conditions are satisfied: + +- Both the origin and destination chains support Circle CCTP +- The selected token is native Circle-issued USDC + +### ETH Bridge {: #eth-bridge} + +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. + +This route appears if all of the following conditions are satisfied: + +- Both the origin and destination chains support the ETH Bridge +- The selected token is native ETH, wstETH, or canonical wETH + +### Gas Drop Off {: #gas-drop-off} + +A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. + +This route appears if all of the following conditions are satisfied: + +- Both the origin and destination chains support gas drop off +- An automatic route is selected +- The relayer accepts the selected token to swap into the gas token +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/architecture/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Architecture +description: Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. +categories: NTT, Transfer +--- ## Introduction -The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. +The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. -If you haven't installed the NTT CLI yet, follow the [NTT Installation Guide](/docs/build/transfers/native-token-transfers/deployment-process/installation/#installation){target=\_blank} to set it up before proceeding. -## Table of Commands +## System Components -The following table lists the available NTT CLI commands, descriptions, and examples. +The NTT framework is composed of managers, which oversee the transfer process, and transceivers, which handle cross-chain messaging, ensuring smooth and reliable token transfers. -To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. +### Managers -### General Commands +_Managers_ are responsible for handling the flow of token transfers between different blockchains and ensuring that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. The main tasks of managers include rate-limiting transactions, verifying message authenticity (message attestation), and managing the interaction between multiple transceivers, who are responsible for cross-chain communications. -| Command | Description | Examples | -|-----------------------------------------|-------------------------------------------------------|--------------------------| -| `ntt update` | update the NTT CLI | `ntt update` | -| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | -| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest`| -| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0`| -| `ntt clone
` | initialize a deployment file from an existing contract| `ntt clone Mainnet Solana Sol5678...`| -| `ntt init ` | initialize a deployment file | `ntt init devnet` | -| `ntt pull` | pull the remote configuration | `ntt pull` | -| `ntt push` | push the local configuration | `ntt push` | -| `ntt status` | check the status of the deployment | `ntt status` | +Each manager is assigned to a specific token but can operate across multiple chains. Their key responsibility is to ensure that tokens are securely locked or burned on the source chain before being minted or unlocked on the destination chain. This provides the integrity of token transfers and prevents double-spending. -### Configuration Commands +A manager is responsible for: -| Command | Description | Examples | -|---------------------------------------------|----------------------------------------|-------------------------------------| -| `ntt config set-chain `| set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key`| -| `ntt config unset-chain ` | unset a configuration value for a chain| `ntt config unset-chain Ethereum scan_api_key`| -| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key`| +- **Handling token transfer flow** - upon a transfer request, `NttManager` either locks or burns tokens depending on the configuration, emits a `TransferSent` event, and ensures tokens can’t be accessed on the source chain before leasing them on the destination chain. This process safeguards against double-spending and maintains a secure transfer +- **Rate-limiting** - the `NttManager` contract includes rate-limiting functionality to prevent overloading the network or flooding the target chain. The `NttManager` applies rate limits to manage transfer flow and prevent network congestion. Limits apply to both outgoing and incoming transfers + - **Outbound** - transfers exceeding the outbound limit are queued (if `shouldQueue` is true) or reverted + - **Inbound** - similar limits apply on the destination chain, delaying transfers if capacity is exceeded -### Solana Commands + Rate limit duration and queuing are customizable per chain, and events notify users when transfers hit the limit -| Command | Description | Examples | -|-----------------------------------------------|---------------------------------------------------------|------------------| -| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json`| -| `ntt solana token-authority ` | print the token authority address for a given program ID| `ntt solana token-authority Sol1234...`| -| `ntt solana ata `| print the token authority address for a given program ID| `ntt solana ata Mint123... Owner123... token22`| +- **Message authenticity verification** - the `NttManager` ensures transfer security by verifying message authenticity through multiple attestations from transceivers. For each transfer, a threshold number of attestation signatures must be gathered from transceivers. Once verified, `NttManager` releases tokens on the destination chain, ensuring only authenticated transfers are processed +- **Interaction with transceivers** - `NttManager` collaborates with transceivers, forwarding transfer messages between chains and handling message verification. Transceivers route messages with transfer details to the destination chain, coordinating with `NttManager` to verify that tokens are locked or burned before releasing them on the other side. Transceivers can be customized to work with different security protocols, adding flexibility -## Where to Go Next +### Transceivers -
+_Transceivers_ facilitate cross-chain token transfers by ensuring the accurate transmission of messages between different blockchains. They work in conjunction with managers to route token transfers from the source chain to the recipient chain. Their primary function is to ensure that messages regarding the transfer process are delivered correctly, and that tokens are safely transferred across chains. +While transceivers operate closely with Wormhole's ecosystem, they can also be configured independently of Wormhole's core system, allowing for flexibility. This adaptability allows them to be integrated with various verification backends to accommodate different security needs or platform-specific requirements. -- :octicons-gear-16:{ .lg .middle } **Configure NTT** +Transceivers are entrusted with several responsibilities: - --- +- **Message transmission** - transceivers handle the routing of transfer messages between chains. When a transfer is initiated, the transceiver sends the message (including transfer details like recipient and amount) to the destination chain’s manager for verification and processing +- **Manager coordination** - transceivers work with managers to ensure tokens are locked or burned on the source chain before issuance on the destination chain, reinforcing the security of each transfer +- **Custom verification support** - transceivers can integrate with custom verification backends, allowing flexibility to adapt to different security protocols or chain requirements. This customization enables protocols to use different attestation standards as needed - Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. +How it works: + +1. The transceiver receives instructions from the manager to send messages across chains +2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred +3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain + +![NTT architecture diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-1.webp) + +!!! note + [Learn more](/docs/products/native-token-transfers/concepts/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. + +#### Custom Transceivers + +The NTT framework supports advanced features such as custom transceivers for specialized message verification, enhancing security and adaptability. The architecture includes detailed processes for initiating transfers, managing rate limits, and finalizing token operations, with specific instructions and events outlined for EVM-compatible chains and Solana. + +NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. + +![Custom Attestation with NTT diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-2.webp) + +The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. + +For more details, to collaborate, or to see examples of custom transceivers, [contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors. + +## Lifecycle of a Message + +The lifecycle of a message in the Wormhole ecosystem for Native Token Transfers (NTT) involves multiple steps to ensure secure and accurate cross-chain token transfers. This lifecycle can vary depending on the blockchain being used, and the following explanations focus on the EVM and Solana implementations. The key stages include initiating the transfer, handling rate limits, sending and receiving messages, and finally, minting or unlocking tokens on the destination chain. + +### Transfer + +The process begins when a client initiates a transfer. For EVM, this is done using the `transfer` function, whereas in Solana, the client uses either the `transfer_lock` or `transfer_burn` instruction, depending on whether the program is in locking or burning mode. The client specifies the transfer amount, recipient chain ID, recipient address, and a flag (`should_queue` on both EVM and Solana) to decide whether the transfer should be queued if it hits the rate limit. + +In both cases: + +- If the source chain is in locking mode, the tokens are locked on the source chain to be unlocked on the destination chain +- If the source chain is in burning mode, the tokens are burned on the source chain, and new tokens are minted on the destination chain + +Once initiated, an event (such as `TransferSent` on EVM or a corresponding log on Solana) is emitted to signal that the transfer process has started. + +### Rate Limit + +Both EVM and Solana implement rate-limiting for transfers to prevent abuse or network overload. Rate limits apply to both the source and destination chains. If transfers exceed the current capacity, depending on whether the `shouldQueue` flag is set to true, they can be queued. + +- On EVM, the transfer is added to an outbound queue if it hits the rate limit, with a delay corresponding to the configured rate limit duration. If `shouldQueue` is set to false, the transfer is reverted with an error +- On Solana, the transfer is added to an **Outbox** via the `insert_into_outbox method`, and if the rate limit is hit, the transfer is queued with a `release_timestamp`. If `shouldQueue` is false, the transfer is reverted with a `TransferExceedsRateLimit` error + +Both chains emit events or logs when transfers are rate-limited or queued. + +### Send + +After being forwarded to the Transceiver, the message is transmitted across the chain. Transceivers are responsible for delivering the message containing the token transfer details. Depending on the Transceiver's implementation, messages may be routed through different systems, such as Wormhole relayers or other custom relaying solutions. Once the message is transmitted, an event is emitted to signal successful transmission. + +- In EVM, the message is sent using the `sendMessage` function, which handles the transmission based on the Transceiver's implementation. The Transceiver may use Wormhole relayers or custom relaying solutions to forward the message +- In Solana, the transfer message is placed in an Outbox and released via the `release_outbound` instruction. The Solana transceiver, such as the Wormhole Transceiver, may send the message using the `post_message` instruction, which Wormhole Guardians observe for verification - [:custom-arrow: Configure your NTT deployment](/docs/build/transfers/native-token-transfers/configuration/) +In both cases, an event or log (e.g., `SendTransceiverMessage` on EVM or a similar log on Solana) is emitted to signal that the message has been transmitted. + +### Receive + +Upon receiving the message on the destination chain, an off-chain relayer forwards the message to the destination Transceiver for verification. + +- In EVM, the message is received by the `NttManager` on the destination chain, which verifies the message's authenticity. Depending on the M of N threshold set for the attestation process, the message may require attestations from multiple transceivers +- In Solana, the message is received via the `receive_message` instruction in the Wormhole Transceiver program. The message is verified and stored in a `VerifiedTransceiverMessage` account, after which it is placed in an Inbox for further processing -- :octicons-question-16:{ .lg .middle } **NTT FAQs** +In both chains, replay protection mechanisms ensure that a message cannot be executed more than once. Events or logs are emitted (e.g., `ReceivedMessage` on EVM or `ReceiveMessage` on Solana) to notify that the message has been successfully received. - --- +### Mint or Unlock - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +Finally, after the message is verified and attested to, the tokens can be either minted (if they were burned on the source chain) or unlocked (if they were locked). The tokens are then transferred to the recipient on the destination chain, completing the cross-chain token transfer process. - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) +- On EVM, tokens are either minted (if burned on the source chain) or unlocked (if locked on the source chain). The `TransferRedeemed` event signals that the tokens have been successfully transferred +- On Solana, the tokens are unlocked or minted depending on whether the program is in locking or burning mode. The `release_inbound_unlock` or `release_inbound_mint` instruction is used to complete the transfer, and a corresponding log is produced -
+In both cases, once the tokens have been released, the transfer process is complete, and the recipient receives the tokens. Events are emitted to indicate that the transfer has been fully redeemed. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/security/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) - Configuration -description: This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. +title: Native Token Transfers Security +description: Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. categories: NTT, Transfer --- -# Configure Native Token Transfers (NTT) - -## Get Started - -This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - -
+# Security -- :octicons-clock-16:{ .lg .middle } **Rate Limiting** +## Global Accountant - --- +The Global Accountant is a defense-in-depth security feature that checks the integrity of every token transfer. It ensures that chain balances remain isolated and more tokens cannot be burned and transferred out of a chain than were ever minted. - Discover options for configuring rate limits and how queueing effects transaction flow. +This feature ensures native asset fungibility remains in 1:1 parity. At no time will assets coming from a spoke chain exceed the number of native assets sent to that spoke chain. The Guardians, with their role in enforcing accounting transparency, provide a reassuring layer of security, attesting to a Native Token Transfer (NTT) only if it passes integrity checks. - [:custom-arrow: Explore rate limit options](/docs/build/transfers/native-token-transfers/configuration/rate-limiting/) +[Contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors if you are interested in configuring the Global Accountant for your multichain deployment. -- :octicons-unlock-16:{ .lg .middle } **Access Control** +## Governance and Upgradeability - --- +Integrators should implement governance mechanisms to manage the addition and removal of transceivers and to upgrade contracts using proxy patterns, as demonstrated in the upgrade functions in the `NttManager` contracts. These processes can also set thresholds and rules for attestation and message approval. - Learn more about access control, including why you should consider setting a separate Pauser address as part of your development security plan. +The registry component of the NTT system is crucial for maintaining a trusted list of transceivers and managing their status. Governance processes for the following actions can be submitted directly to the corresponding contract on-chain, whether it is one or multiple of the bridging contracts or one of the token contracts: - [:custom-arrow: Explore access control roles](/docs/build/transfers/native-token-transfers/configuration/access-control/) +- Adding or removing a transceiver address from the registry +- Setting the token contract address on a bridging contract +- Setting the Wormhole Core Contract address on a bridging contract +- Setting the registered bridging contract address on the token contract -
+This governance model ensures that the system remains secure while being adaptable to new requirements in any environment where it is deployed. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/access-control/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/access-control/ --- BEGIN CONTENT --- --- title: Native Token Transfers Access Control @@ -5203,7 +4921,7 @@ The `Owner` and the `Pauser` addresses can each pause the contract. Since the co Consider separating `Owner` and `Pauser` roles for your multichain deployment. `Owner` and `Pauser` roles are defined directly on the `NttManager` contract. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/rate-limiting/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/rate-limiting/ --- BEGIN CONTENT --- --- title: Native Token Transfers Rate Limiting @@ -5302,74 +5020,371 @@ Queuing is configured dynamically during each transfer by passing the `shouldQue If users bridge frequently between a given source chain and destination chain, the capacity could be exhausted quickly. Loss of capacity can leave other users rate-limited, potentially delaying their transfers. The outbound transfer cancels the inbound rate limit on the source chain to avoid unintentional delays. This allows for refilling the inbound rate limit by an amount equal to the outbound transfer amount and vice-versa, with the inbound transfer canceling the outbound rate limit on the destination chain and refilling the outbound rate limit with an amount. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/faqs/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) - Deployment -description: This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. +title: Native Token Transfers FAQs +description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. categories: NTT, Transfer --- -# Deploy Native Token Transfers (NTT) +# Wormhole NTT FAQs -## Get Started +## Do you have an example of how cross-chain lending can be implemented using Wormhole? -This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. +Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. -
+Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/products/messaging/overview/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. -- :octicons-download-16:{ .lg .middle } **Installation** +## What causes the "No protocols registered for Evm" error in Wormhole SDK? - --- +This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. - Prerequisites and commands for installing the NTT CLI and working with the NTT framework. +To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: - [:custom-arrow: Install the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/) +```rust +import '@wormhole-foundation/sdk-evm-ntt'; +``` -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** +By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. - --- +## How can I transfer ownership of NTT to a multisig? + +Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. + +1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) +2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer +3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) + +For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. + +## How can I specify a custom RPC for NTT? + +To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. + +Below’s an example of how the `overrides.json` file should be structured: + +???- code "`overrides.json`" + ```json + { + "chains": { + "Bsc": { + "rpc": "http://127.0.0.1:8545" + }, + "Sepolia": { + "rpc": "http://127.0.0.1:8546" + }, + "Solana": { + "rpc": "http://127.0.0.1:8899" + } + } + } + ``` + +## How can I redeem tokens if NTT rate limits block them on the target chain? + +If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. + +To resolve this: + +1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed +2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain + +In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. + +## What are the challenges of deploying NTT to non-EVM chains? + +NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. + +## Does the NTT manager function as an escrow account for a hub chain? + +Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. + +## Which functions or events does Connect rely on for NTT integration? + +Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: + +- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain +- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion + +These functions ensure Connect can handle token transfers and manage chain-rate limits. + +## How does the relayer contract determine which transceiver to call? + +The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. + +## How do I create a verifier or transceiver? + +To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. + +For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. + +## Can I use Hetzner for the NTT deployment? + +No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. + +## How can I transfer tokens with NTT with an additional payload? + +You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. + +- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message +- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message + +!!!Important + You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. + +## Why use NTT over xERC20? + +Shortcomings of xERC20: + +- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach +- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies +- **No access control** - there are no built-in access controls for managing token transfers securely +- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security +- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups + +While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. + +## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? + +To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. + +## Is there a way to use NTT tokens with chains that don't currently support NTT? + +Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. For example: + +- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) +- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism +- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT + +This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. + +## How can I update my NTT CLI version? + +To update an existing NTT CLI installation, run the following command in your terminal: + +```bash +ntt update +``` + +NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. + +For local development, you can update your CLI version from a specific branch or install from a local path. + +To install from a specific branch, run: + +```bash +ntt update --branch foo +``` + +To install locally, run: +```bash +ntt update --path path/to/ntt/repo +``` + +Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with NTT +description: NTT enables cross-chain token movement without wrapping. Install the CLI, deploy test tokens, and scaffold a project to integrate NTT into your app. +categories: NTT, Transfer +--- + +# Get Started with NTT + +## Introduction + +The [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview){target=\_blank} framework enables seamless cross-chain token movement without wrapping or liquidity pools. This guide shows you how to install the NTT CLI, which is used to configure and deploy native token contracts, and scaffold your first project for deployment on testnet or mainnet. + +If you are looking for a no-code experience to deploy on mainnet, you can explore the [NTT Launchpad](https://ntt.wormhole.com){target=\_blank}. - Find information on preparing for NTT deployment to EVM, including an example NTT token repository. +## Prerequisites + +Before you begin, make sure you have: + +- [Node.js and npm installed](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} +- [Bun installed](https://bun.sh/){target=\_blank} +- A wallet private key with tokens on supported chains +- ERC-20 or SPL tokens already deployed on the source and destination chains + +## Don’t Have a Token Yet? + +To use NTT, you must have a token already deployed on the source and destination chains. If you don’t have one, follow the quick guides below to deploy a basic test token. + +???- interface "Deploy an ERC-20 Token on EVM" + Use the [example NTT token repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} to deploy a basic ERC-20 token contract on testnet. + + 1. **Install Foundry** - install the [Forge CLI](https://book.getfoundry.sh/getting-started/installation){target=\_blank} + + 2. **Clone the repository** – fetch the example contract repository + + ```bash + git clone https://github.com/wormhole-foundation/example-ntt-token.git + cd example-ntt-token + ``` + + 3. **Deploy the token contract** – deploy to testnet with your preferred name, symbol, minter, and owner addresses + + ```bash + forge create --broadcast \ + --rpc-url INSERT_RPC_URL \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + src/PeerToken.sol:PeerToken \ + --constructor-args "INSERT_TOKEN_NAME" "INSERT_TOKEN_SYMBOL" INSERT_MINTER_ADDRESS INSERT_OWNER_ADDRESS + ``` + + 4. **Mint tokens** – send tokens to your address + + ```bash + cast send INSERT_TOKEN_ADDRESS \ + "mint(address,uint256)" \ + INSERT_RECIPIENT_ADDRESS \ + INSERT_AMOUNT_IN_WEI \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + --rpc-url INSERT_RPC_URL + ``` + + !!! note + This token uses 18 decimals by default. All minting values must be specified in `wei` (1 token = 10^18). + + +???- interface "Create and Mint SPL Tokens" + This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. + + 1. **Generate a Solana key pair** - run the following command to create a new wallet: + + ```bash + solana-keygen grind --starts-with w:1 --ignore-case + ``` + + 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: + + ```bash + solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON + ``` + + 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: + + === "Mainnet" + ```bash + solana config set -um + ``` + + === "Testnet" + ```bash + solana config set -ut + ``` + + === "Devnet" + ```bash + solana config set -ud + ``` + + 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: + + ```bash + solana airdrop 2 + solana balance + ``` + + 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} + + ```bash + cargo install spl-token-cli + ``` + + 6. **Create a new SPL token** - initialize the token on Solana + + ```bash + spl-token create-token + ``` + + 7. **Create a token account** - generate an account to hold the token + + ```bash + spl-token create-account INSERT_TOKEN_ADDRESS + ``` + + 8. **Mint tokens** - send 1000 tokens to the created account + + ```bash + spl-token mint INSERT_TOKEN_ADDRESS 1000 + ``` + + !!! note + NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. + +## Install NTT CLI + +
- [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) +The NTT CLI is recommended to deploy and manage your cross-chain token configuration. -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains via Launchpad** +1. Run the installation command in your terminal: - --- + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` - Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. +2. Verify the NTT CLI is installed: - [:custom-arrow: Deploy via Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/) + ```bash + ntt --version + ``` -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +## Initialize a New NTT Project - --- +1. Once the CLI is installed, scaffold a new project by running: - Your guide to NTT deployment to Solana, including setup, token compatibility, mint/burn modes, and CLI usage. + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) +2. Initialize a new `deployment.json` file specifying the network: -- :octicons-search-16:{ .lg .middle } **Post Deployment** + === "Mainnet" + ```bash + ntt init Mainnet + ``` - --- + === "Testnet" + ```bash + ntt init Testnet + ``` - Learn how to best monitor and maintain your NTT deployment to get the most out of your Wormhole integration while providing security for users. + After initialization, the `deployment.json` file contains your NTT configuration and starts with the selected network. - [:custom-arrow: Explore next steps](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) + === "Mainnet" + ```json + { + "network": "Mainnet", + "chains": {} + } + ``` -- :octicons-alert-16:{ .lg .middle } **Troubleshooting** + === "Testnet" + ```json + { + "network": "Testnet", + "chains": {} + } + ``` - --- +In the deployment steps, you will add your supported chains, their token addresses, deployment modes, and any custom settings. - Explore solutions and detailed guidance in our troubleshooting guide to resolve issues with NTT deployment. +## Next Steps - [:custom-arrow: Get help](/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/) +You have scaffolded your NTT project and initialized the configuration file. Next, follow the appropriate guide below to configure your supported chains and deploy NTT contracts: -
+- [Deploy to EVM](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank}: Deploy NTT on EVM-compatible chains. +- [Deploy to Solana](/docs/products/native-token-transfers/guides/deploy-to-solana/){target=\_blank}: Deploy NTT on Solana. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-evm/ --- BEGIN CONTENT --- --- title: Native Token Transfers EVM Deployment @@ -5377,7 +5392,11 @@ description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for categories: NTT, Transfer --- -# Native Token Transfers (NTT) EVM Development +# Deploy Native Token Transfers (NTT) to EVM Chains + +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of ERC-20 tokens on [supported EVM-compatible chains](/docs/products/reference/supported-networks/#ntt){target=\_blank} using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. + +This guide walks you through deploying NTT on EVM chains, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. ## Deploy Your Token and Ensure Compatibility @@ -5385,20 +5404,20 @@ If you still need to do so, deploy the token contract to the destination or spok ### Requirements for Token Deployment -Wormhole’s NTT is an open framework that supports various deployment modes. The NTT CLI currently supports two deployment modes: burn-and-mint and hub-and-spoke. These modes differ in how tokens are managed across chains. +Wormhole’s NTT framework supports two [deployment models](/docs/products/native-token-transfers/overview#deployment-models){target=\_blank}: burn-and-mint and hub-and-spoke. **Both require an ERC-20 token (new or existing).** -#### Burn-and-Mint Mode +??? interface "Burn-and-Mint" -Tokens integrated with `NttManager` in `burning` mode require the following two functions to be present: + Tokens must implement the following non-standard ERC-20 functions: -- `burn(uint256 amount)` -- `mint(address account, uint256 amount)` + - `burn(uint256 amount)` + - `mint(address account, uint256 amount)` -These functions aren't part of the standard ERC-20 interface. The [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} documents the required functions and convenience methods, errors, and events. + These functions aren't part of the standard ERC-20 interface. Refer to the [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} for all required functions, errors, and events. -??? code "View the complete `INttToken` Interface`" - ```solidity - // SPDX-License-Identifier: Apache 2 + ??? interface "`INttToken` Interface" + ```solidity + // SPDX-License-Identifier: Apache 2 pragma solidity >=0.8.8 <0.9.0; interface INttToken { @@ -5434,54 +5453,86 @@ interface INttToken { // found in the `ERC20Burnable` interface. function burn(uint256 amount) external; } - ``` - -Later, you set mint authority to the corresponding `NttManager` contract. You can also follow the scripts in the [example NTT token](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} repository to deploy a token contract. + ``` -#### Hub-and-Spoke Mode + You’ll also need to set mint authority to the relevant `NttManager` contract. Example deployment scripts are available in the [`example-ntt-token` GitHub repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank}. -A central hub chain (e.g., Ethereum) manages the total token supply in hub-and-spoke mode. Other chains (spokes) mint or burn tokens during cross-chain transfers, ensuring consistency with the locked tokens on the hub chain. +??? interface "Hub-and-Spoke Mode" - - **Hub chain** - tokens are locked on the hub chain when transferring to spoke chains - - **Spoke chains** - tokens are native to the spoke chains and are either minted or burned during cross-chain transfers + Tokens only need to be ERC-20 compliant. The hub chain serves as the source of truth for supply consistency, while only spoke chains need to support minting and burning. For example, if Ethereum is the hub and Polygon is a spoke: -!!! note - The only requirement for using the NTT framework is an ERC20 token, which can be newly deployed or existing. Steps like setting mint authority apply only to spoke chains. + - Tokens are locked on Ethereum + - Tokens are minted or burned on Polygon -For example, when transferring tokens from Ethereum (hub) to Polygon (spoke), the NTT Manager locks tokens on Ethereum, and the corresponding amount is minted on Polygon. Similarly, transferring tokens back from Polygon to Ethereum burns the tokens on Polygon and unlocks the equivalent tokens on Ethereum. + This setup maintains a consistent total supply across all chains. -This process ensures that the total token supply remains consistent across all chains, with the hub chain acting as the source of truth. +## NTT Manager Deployment Parameters -For more detailed information, see the [Deployment Models](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank} page. +This table compares the configuration parameters available when deploying the NTT Manager using the CLI versus a manual deployment with a Forge script. It highlights which options are configurable via each method, whether values are auto-detected or hardcoded, and includes additional comments to help guide deployment decisions. -### Key Differences Between Modes +|
Parameter
| Forge Script | CLI | Both | Comments | +|-------------------------|------------------------|-------------------------------------|--------|----------------------------------------------| +| `token` | Input | `--token
` | Yes | | +| `mode` | Input | `--mode ` | Yes | Key decision: hub-and-spoke or mint-and-burn | +| `wormhole` | Input | Auto-detected via SDK/`ChainContext` | Similar| | +| `wormholeRelayer` | Input | Auto-detected via on-chain query/SDK| Similar| | +| `specialRelayer` | Input | Not exposed | No | Take into consideration if using custom relaying. Not recommended | +| `decimals` | Input, overridable | Auto-detected via token contract, not overridable | Similar | | +| `wormholeChainId` | Queried from Wormhole contract | `--chain` (network param, mapped internally) | Yes | | +| `rateLimitDuration` | Hardcoded (`86400`) | Hardcoded (`86400`) | Yes | Rate limit duration. A day is normal but worth deciding | +| `shouldSkipRatelimiter` | Hardcoded (`false`) | Hardcoded (`false`) | Yes | If rate limit should be disabled (when the manager supports it) | +| `consistencyLevel` | Hardcoded (`202`) | Hardcoded (`202`) | Yes | `202` (finalized) is the standard — lower is not recommended | +| `gasLimit` | Hardcoded (`500000`) | Hardcoded (`500000`) | Yes | | +| `outboundLimit` | Computed | Auto-detected/Hardcoded | Similar| Relative to rate limit | - - **Burn-and-mint** - tokens must implement custom `mint` and `burn` functions, allowing each chain to manage token issuance independently - - **Hub-and-spoke** - tokens only need to be ERC20 compliant, with the hub chain acting as the source of truth for supply consistency ## Deploy NTT -Create a new NTT project: +Before deploying NTT contracts on EVM chains, you need to scaffold a project and initialize your deployment configuration. -```bash -ntt new my-ntt-deployment -cd my-ntt-deployment -``` +???- interface "Install the NTT CLI and Scaffold a New Project" + + Before proceeding, make sure you have the NTT CLI installed and a project initialized. -Initialize a new `deployment.json` file specifying the network: +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): -=== "Testnet" +1. Install the NTT CLI: ```bash - ntt init Testnet + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash ``` -=== "Mainnet" + Verify installation: + + ```bash + ntt --version + ``` + +2. Initialize a new NTT project: ```bash - ntt init Mainnet + ntt new my-ntt-project + cd my-ntt-project ``` +3. Create the deployment config**: + + === "Mainnet" + + ```bash + ntt init Mainnet + ``` + + === "Testnet" + + ```bash + ntt init Testnet + ``` + + This generates a `deployment.json` file where your deployment settings will be stored. + +Once you've completed those steps, return here to proceed with adding your EVM chains and deploying contracts. + Ensure you have set up your environment correctly: ```bash @@ -5556,10 +5607,10 @@ The final step in the deployment process is to set the NTT Manager as a minter o By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. !!!important - To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} page. + To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} page. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-solana/ --- BEGIN CONTENT --- --- title: Native Token Transfers Solana Deployment @@ -5569,11 +5620,9 @@ categories: NTT, Transfer # Deploy Native Token Transfers on Solana -[Native Token Transfers (NTT)](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. - -This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. -By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. +This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. ## Prerequisites @@ -5660,31 +5709,51 @@ Deploying NTT with the CLI on Solana follows a structured process: !!! note NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. -2. **Choose your [deployment model](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank}**: +2. **Choose your deployment model**: - - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required - - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program + - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required + - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program 3. **Deploy and configure NTT** - use the NTT CLI to initialize and deploy the NTT program, specifying your SPL token and deployment mode +![Solana NTT deployment diagram](/docs/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp) + Following this process, your token will fully integrate with NTT, enabling seamless transfers between Solana and other chains. -By default, NTT transfers to Solana require manual [relaying](/docs/learn/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. +By default, NTT transfers to Solana require manual [relaying](/docs/protocol/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. ## Set Up NTT To integrate your token with NTT on Solana, you must initialize the deployment and configure its parameters. This process sets up the required contracts and may generate key pairs if they don't exist. These key pairs are used to sign transactions and authorize actions within the NTT deployment. -The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: +The [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: + +???- interface "Install the NTT CLI and Scaffold a New Project" + + Before proceeding, make sure you have the NTT CLI installed and a project initialized. + +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): + +1. Install the NTT CLI: + + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` + + Verify installation: + + ```bash + ntt --version + ``` -1. **Create a new NTT project** - set up a deployment workspace +2. Initialize a new NTT project: ```bash - ntt new INSERT_PROJECT_NAME - cd INSERT_PROJECT_NAME + ntt new my-ntt-project + cd my-ntt-project ``` -2. **Initialize the deployment** - generate a `deployment.json` file with your deployment settings +3. Create the deployment config**: === "Mainnet" @@ -5697,17 +5766,19 @@ The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/in ```bash ntt init Testnet ``` -!!! note - Testnet deployment settings work for both Solana Testnet and Devnet networks. + This generates a `deployment.json` file where your deployment settings will be stored. + + !!! note + Testnet deployment settings work for both Solana Testnet and Devnet networks. ### Generate an NTT Program Key Pair Create a unique key pair for the NTT program: - - ```bash - solana-keygen grind --starts-with ntt:1 --ignore-case - ``` + +```bash +solana-keygen grind --starts-with ntt:1 --ignore-case +``` ### Set Mint Authority @@ -5734,7 +5805,7 @@ Follow these steps to set the mint authority using the NTT CLI: ## Deploy and Configure NTT !!! warning - If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/build/transfers/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. + If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/products/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. After setting up your deployment, finalize the configuration and deploy the NTT program on Solana by following these steps: @@ -5800,7 +5871,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i After deploying NTT on Solana, deploy and integrate it on EVM chains to enable seamless multichain transfers. - [:custom-arrow: Deploy NTT on EVM](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} + [:custom-arrow: Deploy NTT on EVM Chains](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Test Your Deployment** @@ -5808,7 +5879,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Follow the NTT Post Deployment Guide for integration examples and testing instructions. - [:custom-arrow: Test Your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} + [:custom-arrow: Test Your NTT deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Add NTT to Your dApp** @@ -5816,7 +5887,15 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Configure Wormhole Connect, a plug-and-play bridging UI, to enable multichain transfers for your token. - [:custom-arrow: Use Connect to Integrate NTT](/docs/build/transfers/connect/){target=\_blank} + [:custom-arrow: Use Connect to Integrate NTT](/docs/products/connect/overview/){target=\_blank} + +- :octicons-question-16:{ .lg .middle } **View FAQs** + + --- + + Find answers to common questions about NTT. + + [:custom-arrow: View FAQs](/docs/products/native-token-transfers/faqs){target=\_blank} - :octicons-question-16:{ .lg .middle } **View FAQs** @@ -5829,7 +5908,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/evm-launchpad/ --- BEGIN CONTENT --- --- title: Deploy Native Token Transfers with Launchpad @@ -5876,8 +5955,8 @@ The NTT Launchpad currently supports deployments on the following mainnet chains Once ready, choose an option to proceed: - - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token) - deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains - - [**Expand Your Existing Token**](#expand-your-existing-token) - if you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract + - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token): Deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains. + - [**Expand Your Existing Token**](#expand-your-existing-token): If you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract. ## Launch a Cross-Chain Token @@ -5885,11 +5964,11 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Launch a Cross-Chain Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp) 3. Set the token details: 1. Select the **home network** from the dropdown menu @@ -5898,22 +5977,22 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 4. Provide the **initial supply** 5. To the token details, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp) 4. Select the deployment chains: 1. The home network where your token will be deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -5925,33 +6004,33 @@ Expand an existing token to support NTT across multiple chains. This process int 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Expand Your Existing Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp) 3. Enter the token details: 1. Choose the home network where your token is already deployed (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp) 4. Select the chains to deploy your token to: 1. The home network where your token is already deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 1. Click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -5961,7 +6040,7 @@ Expand an existing token to support NTT across multiple chains. This process int To access the **Dashboard** from the [Launchpad home page](https://ntt.wormhole.com/){target=\_blank}, click on **Manage Deployment**. Here, you can view deployment status, monitor supply across chains, and configure transfer settings. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp) The dashboard provides a high-level view of your token across all deployed chains, including: @@ -5969,7 +6048,7 @@ The dashboard provides a high-level view of your token across all deployed chain - Supply distribution visualization - List of deployed chains, including inbound and outbound transfer limits, which can be modified in [**Settings**](#settings) -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp) ## Settings @@ -5981,131 +6060,44 @@ Use the drop-down menu at the top to select the chain you want to configure. The From this section, you can also: - - **Pause the token** – temporarily turn off transfers on the selected chain - - **Deploy to a new chain** – expand your token by deploying it to an additional chain + - **Pause the token**: Temporarily turn off transfers on the selected chain. + - **Deploy to a new chain**: Expand your token by deploying it to an additional chain. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp) ### Role Management -This section displays key [roles](/docs/build/transfers/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. +This section displays key [roles](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. - - **Manager’s Owner** – the owner through the `NTTOwner` proxy - - **Pauser** – the address authorized to pause transfers + - **Manager’s Owner**: The owner through the `NTTOwner` proxy. + - **Pauser**: The address authorized to pause transfers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp) ### Security Threshold -Determine and update how transceivers interact with the token. [Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. +Determine and update how transceivers interact with the token. [Transceivers](/docs/products/native-token-transfers/concepts/architecture/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. A higher transceiver threshold increases security by requiring more approvals before processing a transfer, but it may also slow down transactions. A lower threshold allows faster transfers but reduces redundancy in message verification. - - **Registered Transceivers** – displays the number of registered transceivers and their addresses - - **Transceivers Threshold** – a configurable value that must be less than or equal to the number of transceivers + - **Registered Transceivers**: Displays the number of registered transceivers and their addresses. + - **Transceivers Threshold**: A configurable value that must be less than or equal to the number of transceivers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp) ### Peer Chains Limits Define the transfer restrictions for each connected network. You can adjust: - - **Sending Limits** – the maximum amount of tokens that can be sent from the home chain - - **Receiving Limits** – the maximum amount of tokens that can be received for each of the supported peer chains + - **Sending Limits**: The maximum amount of tokens that can be sent from the home chain. + - **Receiving Limits**: The maximum amount of tokens that can be received for each of the supported peer chains. Enter a new value to adjust limits and click **Update**. The changes will take effect immediately. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp) ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/installation/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Installation -description: Learn how to Install Wormhole’s Native Token Transfers (NTT) framework, a flexible and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- - -# Install the Native Token Transfers CLI - -In this video, the Wormhole team walks you through installing the [Native Token Transfers (NTT) CLI](https://github.com/wormhole-foundation/native-token-transfers/tree/main/cli){target=\_blank}. You’ll see a practical demonstration of running commands, verifying your installation, and addressing common issues that might arise. If you prefer to follow written instructions or want a quick reference for each step, scroll down for the detailed installation guide. - -To start using the NTT CLI, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. - -
- -## Install NTT CLI - -The fastest way to deploy Native Token Transfers (NTT) is using the NTT CLI. As prerequisites, ensure you have the following installed: - -- Install [Bun](https://bun.sh/docs/installation){target=\_blank} - -Follow these steps to install the NTT CLI: - -1. Run the installation command in your terminal: - - ```bash - curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash - ``` - -2. Verify the NTT CLI is installed: - - ```bash - ntt --version - ``` - -3. Once installed, check out the available [NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/){target=\_blank} to start using the CLI - -## Update NTT CLI - -To update an existing NTT CLI installation, run the following command in your terminal: - -```bash -ntt update -``` - -NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. - -For local development, you can update your CLI version from a specific branch or install from a local path. - -To install from a specific branch, run: - -```bash -ntt update --branch foo -``` - -To install locally, run: -```bash -ntt update --path path/to/ntt/repo -``` - -Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. - -## Where to Go Next - -
- - -- :octicons-tools-16:{ .lg .middle } **Deploy to EVM Chains** - - --- - - Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to EVM chains](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) - -- :octicons-tools-16:{ .lg .middle } **Deploy to Solana** - - --- - - Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy NTT to Solana](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) - -
+![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp) --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/post-deployment/ --- BEGIN CONTENT --- --- title: Native Token Transfers Post Deployment @@ -6118,9 +6110,9 @@ categories: NTT, Transfer To offer the best user experience and ensure the most robust deployment, Wormhole contributors recommend the following after you have deployed Native Token Transfers (NTT): - Implement a robust testing plan for your multichain token before launching -- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/build/transfers/native-token-transfers/configuration/){target=\_blank} for more details on ownership and rate limits -- Consider a streamlined, customizable frontend such as [Wormhole Connect](/docs/build/transfers/connect/){target=\_blank} for an optimized user experience -- Alternatively, the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} allows for a direct integration into your infrastructure +- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} for more details on ownership and rate limits +- Consider a streamlined, customizable frontend such as [Connect](/docs/products/connect/overview/){target=\_blank} for an optimized user experience +- Alternatively, the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} allows for a direct integration into your infrastructure - Ensure ecosystem actors such as block explorers, automated security tools (such as BlockAid and Blowfish), and wallets (such as MetaMask, Backpack, and Phantom) are aware of your multichain deployment and that it is labeled appropriately - Monitor and maintain your multichain deployment @@ -6130,6 +6122,20 @@ By default, NTT transfers to Solana require manual relaying, meaning that after This step ensures that tokens are properly minted or unlocked on Solana and prevents unauthorized claims. +## Post-Deployment Settings + +The following table outlines post-deployment settings available on the NTT Manager contract. These allow you to update roles, pause activity, and adjust transfer limits—useful for upgrades, incident response, or protocol tuning after initial deployment. + +| Setting | Effect | +|-------------------------|------------------------------------------| +| `pause` | Pauses the manager | +| `unpause` | Unpauses the manager | +| `setOwner` | Changes the manager owner | +| `setPauser` | Changes the pauser role | +| `setOutboundLimit` | Sets outbound transfer limit | +| `setInboundLimit` | Sets inbound transfer limit (per chain) | +| `setTransceiverPauser ` | Changes pauser for a transceiver | + ## Where to Go Next
@@ -6138,7 +6144,7 @@ This step ensures that tokens are properly minted or unlocked on Solana and prev --- - Check out an example project that uses a Vite-React TypeScript application and integrates it with Wormhole Connect, a customizable widget for cross-chain asset transfers. + Check out an example project that uses a Vite-React TypeScript application and integrates it with Connect, a customizable widget for cross-chain asset transfers. [:custom-arrow: Explore the NTT Connect demo](https://github.com/wormhole-foundation/demo-ntt-connect) @@ -6153,7 +6159,7 @@ This step ensures that tokens are properly minted or unlocked on Solana and prev
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/troubleshoot/ --- BEGIN CONTENT --- --- title: Troubleshooting NTT Deployment @@ -6161,19 +6167,19 @@ description: Resolve common issues in NTT deployment with this troubleshooting g categories: NTT, Transfer --- -# Troubleshooting NTT Deployment +# Troubleshoot Your NTT Deployment If you encounter issues during the NTT deployment process, check the following common points: -- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#install-dependencies){target=\_blank} +- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/products/native-token-transfers/guides/deploy-to-solana/#install-dependencies){target=\_blank} - [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** - [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** - **Token compliance on EVM** - verify that your token is an ERC20 token on the EVM chain - **Mint authority transfer** - - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section - - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details -- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#configure-ntt){target=\_blank} section -- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#configure-ntt){target=\_blank} + - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/products/native-token-transfers/guides/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section + - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/products/native-token-transfers/guides/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details +- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/products/native-token-transfers/guides/deploy-to-solana/#configure-ntt){target=\_blank} section +- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/products/native-token-transfers/guides/deploy-to-evm/#configure-ntt){target=\_blank} - **Docker environment based on Ubuntu 20.04 with all dependencies required for Wormhole NTT CLI development** - run `docker compose up -d` to start the container in your terminal from the directory containing the `docker-compose.yml` file ???- interface "Dockerfile" @@ -6262,147 +6268,166 @@ If you encounter issues during the NTT deployment process, check the following c ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/faqs/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/overview/ --- BEGIN CONTENT --- --- -title: Native Token Transfers FAQs -description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +title: Native Token Transfers Overview +description: With Native Token Transfers, you can directly transfer a blockchain's native assets across various connected networks. categories: NTT, Transfer --- -# Wormhole NTT FAQs +## Native Token Transfers Overview -## Do you have an example of how cross-chain lending can be implemented using Wormhole? +Native Token Transfers (NTT) provides an adaptable framework for transferring your native tokens across different blockchains. Unlike traditional wrapped assets, NTT maintains your token's native properties on every chain. This ensures that you retain complete control over crucial aspects, such as metadata, ownership, upgradeability, and custom features. -Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. +## Key Features -Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/learn/transfers/native-token-transfers/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. +- **Control and customization**: Ensure ownership and configurable access controls, permissions, and thresholds, preventing unauthorized calls. +- **Advanced rate limiting**: Set rate limits per chain and period to prevent abuse, manage network congestion, and control deployments. +- **Global accountant**: Ensures the amount burned and transferred on chains never exceeds the amount of tokens minted. +- **No wrapped tokens**: Tokens are used directly within their native ecosystem, eliminating intermediary transfer steps. -## What causes the "No protocols registered for Evm" error in Wormhole SDK? -This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. +## Deployment Models -To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: +NTT offers two operational modes for your existing tokens: -```rust -import '@wormhole-foundation/sdk-evm-ntt'; -``` +- **Hub-and-spoke**: Locks tokens on a central "hub" chain and mints equivalents on "spoke" chains, maintaining the total supply on the hub. It's ideal for integrating existing tokens onto new blockchains without altering their original contracts. +- **Burn-and-mint**: Burns tokens on the source chain and mints new ones on the destination, distributing the total supply across multiple chains. It's best suited for new token deployments or projects willing to upgrade existing contracts for a truly native multichain token. -By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. +## Supported Token Standards -## How can I transfer ownership of NTT to a multisig? +Native Token Transfers (NTT) primarily support ERC-20 tokens, the most widely used standard for fungible assets on Ethereum and other EVM-compatible chains, including ERC-20 Burnable tokens, which can be burned on the source chain during cross-chain transfers when required. It also supports fungible SPL tokens on Solana for secure cross-chain transfers. -Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. +The NttManager is a contract that oversees the secure and reliable transfer of native tokens across supported blockchains. It leverages the standard IERC20 interface and OpenZeppelin’s SafeERC20 library to interact with these tokens securely across chains. -1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) -2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer -3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) +NTT does not currently support token standards like ERC-721 (non-fungible tokens), ERC-1155 (a multi-token standard), or SPL-based tokens, such as Metaplex NFTs. Support is currently limited to ERC-20 tokens. -For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. +## Deployment Process -## How can I specify a custom RPC for NTT? +Here's a breakdown of the key steps involved when deploying NTT: -To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. +- **Prepare tokens**: Ensure your ERC-20 or SPL tokens are ready. +- **Choose deployment model**: Choose your cross-chain token model: either burn-and-mint or hub-and-spoke. +- **Choose deployment tool**: Use the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for EVM chains only) or the [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank}. +- **Initialization**: Specify target chains and token details, and set up your CLI environment if using it. +- **Deploy contracts**: Deploy NTT Manager contracts to all selected chains, confirming transactions and covering gas fees. +- **Finalize configurations**: Grant minting authority, configure rate limits, establish peer manager connections, and assign administrative roles. +- **Monitor and maintain**: Verify deployment, monitor total supply with the [Global Accountant](/docs/products/native-token-transfers/concepts/security/#global-accountant){target=\_blank}, and adjust configurations as needed. -Below’s an example of how the `overrides.json` file should be structured: +## Use Cases -???- code "`overrides.json`" - ```json - { - "chains": { - "Bsc": { - "rpc": "http://127.0.0.1:8545" - }, - "Sepolia": { - "rpc": "http://127.0.0.1:8546" - }, - "Solana": { - "rpc": "http://127.0.0.1:8899" - } - } - } - ``` +- **Cross-Chain Swaps and Liquidity Aggregation** -## How can I redeem tokens if NTT rate limits block them on the target chain? + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transmits native assets across chains. + - [**Connect**](/docs/products/connect/overview/): Manages user-friendly asset transfers. + - [**Queries**](/docs/products/queries/overview/): Acquires real-time prices for optimal trade execution. -If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. +- **Borrowing and Lending Across Chains** -To resolve this: + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Moves collateral as native assets. + - [**Messaging**](/docs/products/messaging/overview/): Propagates loan requests and liquidations across chains. + - [**Queries**](/docs/products/queries/overview/): Retrieves interest rates and asset prices in real-time. -1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed -2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain +- **Gas Abstraction** -In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Facilitates native token conversion for gas payments. + - [**Messaging**](/docs/products/messaging/overview/): Sends gas fee payments across chains. -## What are the challenges of deploying NTT to non-EVM chains? +- **Cross-Chain Payment Widgets** -NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Ensures direct, native asset transfers. + - [**Connect**](/docs/products/connect/overview/): Facilitates seamless payments in various tokens. -## Does the NTT manager function as an escrow account for a hub chain? +- **Cross-Chain Staking** -Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transfers staked assets natively between networks. + - [**Messaging**](/docs/products/messaging/overview/): Moves staking rewards and governance signals across chains. -## Which functions or events does Connect rely on for NTT integration? +## Next Steps -Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: +Follow these steps to get started with NTT: -- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain -- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion +[timeline(wormhole-docs/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json)] +--- END CONTENT --- -These functions ensure Connect can handle token transfers and manage chain-rate limits. +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/cli-commands/ +--- BEGIN CONTENT --- +--- +title: NTT CLI Commands +description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +categories: NTT, Transfer +--- -## How does the relayer contract determine which transceiver to call? +# NTT CLI Commands -The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. +## Introduction -## How do I create a verifier or transceiver? +The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. -To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. +If you haven't installed the NTT CLI yet, follow the [NTT Installation](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank} instructions to set it up before proceeding. -For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. +## Table of Commands -## Can I use Hetzner for the NTT deployment? +The following table lists the available NTT CLI commands, descriptions, and examples. -No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. +To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. -## How can I transfer tokens with NTT with an additional payload? +### General Commands -You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. +| Command | Description | Example | +|-----------------------------------------|--------------------------------------------------------|--------------------------------------------------------------------| +| `ntt update` | update the NTT CLI | `ntt update` | +| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | +| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest` | +| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0` | +| `ntt clone
` | initialize a deployment file from an existing contract | `ntt clone Mainnet Solana Sol5678...` | +| `ntt init ` | initialize a deployment file | `ntt init devnet` | +| `ntt pull` | pull the remote configuration | `ntt pull` | +| `ntt push` | push the local configuration | `ntt push` | +| `ntt status` | check the status of the deployment | `ntt status` | -- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message -- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message +### Configuration Commands + +| Command | Description | Example | +|----------------------------------------------|-----------------------------------------|------------------------------------------------| +| `ntt config set-chain ` | set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key` | +| `ntt config unset-chain ` | unset a configuration value for a chain | `ntt config unset-chain Ethereum scan_api_key` | +| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key` | + +### Solana Commands + +| Command | Description | Example | +|------------------------------------------------|----------------------------------------------------------|-------------------------------------------------| +| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json` | +| `ntt solana token-authority ` | print the token authority address for a given program ID | `ntt solana token-authority Sol1234...` | +| `ntt solana ata ` | print the token authority address for a given program ID | `ntt solana ata Mint123... Owner123... token22` | + +## Where to Go Next -!!!Important - You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. +
-## Why use NTT over xERC20? -Shortcomings of xERC20: +- :octicons-gear-16:{ .lg .middle } **Configure NTT** -- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach -- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies -- **No access control** - there are no built-in access controls for managing token transfers securely -- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security -- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups + --- -While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. + Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? + [:custom-arrow: Configure your NTT deployment](/docs/products/native-token-transfers/configuration/access-control/) -To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. +- :octicons-question-16:{ .lg .middle } **NTT FAQs** -## Is there a way to use NTT tokens with chains that don't currently support NTT? + --- -Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. For example: + Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. -- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) -- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism -- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT + [:custom-arrow: Check out the FAQs](/docs/products/native-token-transfers/faqs/) -This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/managers-transceivers/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/managers-transceivers/ --- BEGIN CONTENT --- --- title: Managers and Transceivers @@ -6700,42 +6725,181 @@ Program log: Instruction: ReleaseInboundUnlock ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/ +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- + +# Products + +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. + +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. + +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. + +## Transfer Products + +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. + +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods + +
+ +::spantable:: + +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | + +::end-spantable:: + +
+ +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: + +
+ +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. + +## Bridging UI + +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. + +## Real-time Data + +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + +## Multichain Governance + +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/settlement/concepts/architecture/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement -description: Start building with Wormhole Settlement; integrate with the Liquidity Layer and set up Solvers to enable seamless cross-chain asset transfers. +title: Settlement Protocol Architecture +description: Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. categories: Settlement, Transfer --- -# Wormhole Settlement +# Settlement Protocol Architecture -## Get Started +## Introduction -This section provides resources to build with Wormhole Settlement, including integrating the Liquidity Layer into your application and running a Solver for efficient cross-chain asset transfers. +This page describes the high-level mechanics of the underlying native swap protocols in the Wormhole SDK. While built on Wormhole messaging, each protocol uses a novel architecture with unique price discovery, scalability, and latency tradeoffs. These designs enable redundancy to handle highly asymmetric flows and sharp volume changes. These sections will cover the following: -
+- **Wormhole Liquidity Layer** - a cross-chain transfer protocol that utilizes Solana as the central orchestration layer for cross-chain intents, allowing solvers to deploy liquidity from a single Solana-based hub rather than distributing it across each supported chain +- **Mayan Swift** - a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent +- **Mayan MCTP** - a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains -- :octicons-code-16:{ .lg .middle } **Build on the Liquidity Layer** +## Wormhole Liquidity Layer - --- +Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster-than-finality transfers across the Wormhole ecosystem through a novel, Solana-based hub-and-spoke architecture. The hub-and-spoke model leverages interoperable token standards like Circle's CCTP (and Wormhole's NTT), allowing the solver to natively mint and burn assets between chains for intent fulfillment. This architecture allows solvers to facilitate cross-chain transfers by fronting assets on the destination chain and assuming the finality risk of the originating source chain transaction. + +Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. - Integrate seamlessly with Wormhole's Liquidity Layer, learn key EVM contract functions for fast and secure cross-chain transfers. +![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/products/settlement/concepts/architecture/architecture-1.webp) - [:custom-arrow: Build on the Liquidity layer](/docs/build/transfers/settlement/liquidity-layer/) +The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. -- :octicons-code-16:{ .lg .middle } **Run a Settlement Solver** +### Solvers and Liquidity Fragmentation - --- +Traditional intent-based protocols require solvers to distribute their capital across each supported chain in the network. This liquidity fragmentation leads to capital inefficiency and requires complex rebalancing to manage asymmetric flows between chains. As the number of chains increases, solvers face scalability challenges, which can result in market concentration, reducing competition and potentially impacting price discovery in intent execution. - Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. +Using a hub-and-spoke model, the Wormhole Liquidity Layer solves these challenges by consolidating solver liquidity on a single chain, Solana. This model eliminates the need for complex cross-chain rebalancing and simplifies solvers' infrastructure requirements. Solvers only need to consider the finality risk of the originating source chain transaction and the payload size when bidding on transfers. By concentrating liquidity on Solana, the protocol can handle large transfer volumes with a smaller capital base, enhancing capital efficiency and lowering barriers to entry for solvers. This approach promotes competition, improves overall market efficiency, and ultimately benefits users with better prices while still preserving the speed of transactions. - [:custom-arrow: Run a Solver](/docs/build/transfers/settlement/solver/) +### Enable Unified Liquidity -
+The novel hub-and-spoke liquidity architecture relies on interoperable token standards that enable cross-chain token fungibility, such as Circle's Cross-Chain Transfer Protocol (CCTP) and Wormhole's Native Token Transfers (NTT). These protocols allow assets to move seamlessly between chains, making unified liquidity possible. On the liquidity hub (Solana), solvers concentrate their liquidity in NTT or CCTP-supported assets, such as USDC. These assets act as the shuttle between chains but may not necessarily be the user's original or final asset. + +After the Solana auction concludes, the appropriate instructions are called on the CCTP or NTT contract, initiating the transfer from Solana to the destination chain by burning/locking the asset on Solana and sequentially minting on the destination chain. Solvers rebalance their inventory on Solana using these interoperable token standards as well. Once the originating source chain transaction reaches finality and arrives to Solana, the solver can redeem the NTT or CCTP message, minting the inventory for use once again. + +By leveraging interoperable token standards like NTT, this model of liquidity facilitation for cross-chain intents can arbitrarily scale to any chain or ecosystem while preserving fully unified liquidity. This removes the need for solver "buy-in" when expanding to new chains. Additionally, regardless of proven traction, new chains can access the same level of liquidity for cross-chain intent fulfillment from the first day of mainnet launch as long-standing ecosystems with clear evidence of adoption. This is often overlooked by solvers, who must aggressively prioritize high-flow chains due to high opportunity costs. The model also supports ecosystems without Centralized Exchange (CEX) enabled withdrawals. + +### Protocol Flow: How It Works + +1. **Initiation** - users or protocols initiate a transfer via an interface or directly on-chain. They choose between a standard transfer (waiting for finality on the sending chain) or a fast transfer (triggering the auction process). For fast transfers, users or the protocol specify a maximum fee and an auction start deadline + + !!! Note + If an auction doesn't start within the set deadline, a standard transfer will proceed directly from the source to the destination chain. + +2. **Auction** - solvers monitor the Wormhole network for these fast transfer requests and initiate an auction on Solana by offering to fulfill the transfer at or below the user's maximum fee. To start the auction, the solver must transfer the requested funds plus a small security deposit to the Matching Engine contract +3. **Competition** - once initiated, other solvers can participate by submitting lower bids in a simple English auction, aiming to provide users with the best rate. If a new solver submits a better offer, the previous solver's funds and security deposit are returned, with the latest offer taking precedence atomically. This competition ensures that users receive the best possible transfer rate +4. **Fulfillment** - after the auction concludes, the winning solver must complete the transfer within a predefined grace period to earn their fee and reclaim their security deposit. Failure to do so may result in the security deposit being slashed, with the slashed amount compensating the user for delays. This mechanism incentivizes prompt execution. Upon successful completion, the Fast Transfer hub sends the USDC to the user's destination wallet, and the solver receives their security deposit and transfer fee +5. **Settlement** - once the source chain transaction reaches finality, the winning solver can use the finalized Wormhole message to settle the auction with the matching engine and rebalance. This allows the solver to retrieve the original transfer amount into their wallet + +## Mayan Swift + +Mayan Swift is a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent. + +### On-Chain Competitive Price Discovery Mechanism + +Traditional intent-based protocols essentially function as cross-chain limit orders. If the order is profitable, solvers will compete to fulfill it, leading to MEV-like competition focused on speed. While functional, this methodology presents two clear inefficiencies and drawbacks. + +First, they lack a competitive price discovery mechanism as limit order prices are typically determined through centralized off-chain systems. Second, in this MEV-like market structure, only a single solver can win, while the others lose out on transaction fees. This dynamic of deadweight loss results in solvers prioritizing high-margin orders, ultimately resulting in elevated fees for end-users without commensurate benefits. + +Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. + +![Mayan Swift - Intent-centric design](/docs/images/products/settlement/concepts/architecture/architecture-2.webp) + +### Protocol Flow: How It Works + +1. **Initiation** - the user creates an order by signing a transaction that locks one of the primary assets (USDC or ETH) into the Mayan smart contract, specifying the desired outcome. + + !!!note + If the input asset is not a primary asset, it is converted into a primary asset within the same transaction before the order is submitted. + + Each order includes properties such as destination chain, destination wallet address, output token address, minimum output amount, gas drop amount, deadline, and 32 bytes of random hex to prevent collisions. A Keccak-256 hash is then calculated to identify the order + +2. **Auction** - solvers observe on-chain data or subscribe to the Mayan explorer web socket (solvers using the Mayan explorer verify the order's integrity by checking the data against the on-chain hash). Once the new order is verified, an on-chain auction on Solana is initiated by passing the order ID and the bid amount, which cannot be lower than the minimum amount. Other solvers can increase the bid by submitting a higher amount before the auction ends +3. **Fulfillment** - the auction ends three seconds after the initial bid. Once the auction ends, the winning solver can execute an instruction that passes their wallet address on the destination chain. This triggers a Wormhole message containing the order ID and the winner's wallet address. Wormhole Guardians then sign this message, allowing the winning solver to fulfill the order on the destination chain by submitting proof of their win and the promised amount to the Mayan contract before the deadline. The Mayan contract deducts a protocol fee (currently 3 basis points) and a referral fee (if applicable), transferring the remaining amount to the user's destination wallet. It also triggers a Wormhole message as proof of fulfillment +4. **Settlement** - after the Wormhole Guardians sign the fulfillment message, the winning solver can submit this message on the source chain to unlock the user's funds and transfer them to their own wallet. Upon fulfillment, the solver has the option to delay triggering a Wormhole message immediately. Instead, they can batch the proofs and, once the batch reaches a certain threshold, issue a batched proof to unlock all orders simultaneously, saving on gas fees + +## Mayan MCTP + +Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. + +![Mayan MCTP diagram](/docs/images/products/settlement/concepts/architecture/architecture-3.webp) + +### Protocol Flow: How It Works + +1. **Initiation** - the user creates an order by signing a transaction that locks one USDC into the Mayan smart contract, specifying the desired outcome. + + !!!note + If the input asset is not USDC, it is converted into a primary asset within the same transaction before the order is submitted. + + The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash + +2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} +3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules + +The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. + +## Where to Go Next + +- To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/faqs/ +Doc-Content: https://wormhole.com/docs/products/settlement/faqs/ --- BEGIN CONTENT --- --- title: Wormhole Settlement FAQs @@ -6760,352 +6924,601 @@ After the user receives the token upfront, the execution of additional contract If the slippage tolerance is set too low, the user may receive USDC on the destination chain instead of the intended swap outcome. However, the four basis points (bps) fee is non-refundable, as the service provided by Liquidity Layer (LL) solvers (ensuring front-finality) is separate from the composing protocol's services, such as swaps or deposits. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/liquidity-layer/ +Doc-Content: https://wormhole.com/docs/products/settlement/get-started/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Liquidity Layer -description: Learn how to build on the Wormhole Liquidity Layer, the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. +title: Get Started +description: Perform a cross-chain token swap using Wormhole Settlement and the Mayan Swift route with the TypeScript SDK on mainnet. categories: Settlement, Transfer --- -# Build on the Wormhole Liquidity Layer +# Get Started -## Introduction +[Settlement](/docs/products/settlement/overview/){target=\_blank} is Wormhole’s intent-based execution layer, enabling fast, multichain token transfers. It coordinates routing logic, relayers, and on-chain infrastructure to let users express what they want to be done, not how. -The Wormhole Liquidity Layer is the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. It allows these protocols to bundle call data containing arbitrary actions that can be executed atomically alongside each transfer. This feature enables developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. The following section describes the key smart contract components for teams seeking to build atop Wormhole Settlement. +This guide walks you through performing a real token swap using the [Mayan Swift route](https://mayan.finance){target=_blank}, one of the three integrated Settlement protocols, with the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=_blank}. -## EVM Functions +By the end, you'll have a working script that: -The EVM Token Router is a simple interface against which to integrate. For an integrator, the contracts have two main entry points: `placeMarketOrder` and `placeFastMarketOrder`. +- Resolves token transfer routes using Mayan Swift +- Quotes and validates the best route +- Initiates a swap on a source chain and completes the transfer on a destination chain + +!!! note + Mayan Swift currently supports **mainnet only**. Attempting to run this demo on a testnet will fail. -See the complete list of [Token Router contract addresses](/docs/build/reference/contract-addresses/#settlement-token-router){target=\_blank} for supported networks. +## Prerequisites -### Fast Market Order +Before you begin, ensure you have the following: -The `placeFastMarketOrder` function allows the caller to elect for a _faster-than-finality_ transfer of USDC (with an arbitrary message payload) to the destination chain by setting the `maxFee` and `deadline` parameters. Using this interface does not guarantee that the caller's transfer will be delivered faster than finality; however, any willing market participants can compete for the specified `maxFee` by participating in an auction on the Solana `MatchingEngine` +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#settlement){target=\_blank} -```solidity title="`placeFastMarketOrder` Interface" -function placeFastMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, - uint128 maxFee, - uint32 deadline -) external payable returns (uint64 sequence, uint64 fastSequence); -``` +This example uses Ethereum as the source chain and Solana as the destination. As a result, you'll need an Ethereum wallet with ETH for gas and a Solana wallet with SOL for fees. You can adapt the example to match your preferred chains. -??? interface "Parameters `placeFastMarketOrder()`" +## Set Up a Project - `amountIn` ++"uint128"++ +Start by scaffolding a basic Node.js project and installing the required SDKs. - The amount to transfer. +1. Create a new project folder: - --- + ```bash + mkdir settlement-swap + cd settlement-swap + npm init -y + ``` - `targetChain` ++"uint16"++ +2. Install the required dependencies: - Target chain ID. + ```bash + npm install @wormhole-foundation/sdk-connect \ + @wormhole-foundation/sdk-evm \ + @wormhole-foundation/sdk-solana \ + @mayanfinance/wormhole-sdk-route \ + dotenv + npm install -D typescript tsx + ``` - --- +3. Create the file structure: - `redeemer` ++"bytes32"++ + ```bash + mkdir src + touch src/helpers.ts src/swap.ts .env .gitignore + ``` - Redeemer contract address. +4. Set up secure access to your wallets. This guide assumes you are loading your `MAINNET_ETH_PRIVATE_KEY` and `MAINNET_SOL_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [cast wallet](https://book.getfoundry.sh/reference/cast/cast-wallet/){target=_blank}. - --- + !!! warning + If you use a .env file during development, add it to your .gitignore to exclude it from version control. Never commit private keys or mnemonics to your repository. - `redeemerMessage` ++"bytes"++ +## Perform a Token Swap - An arbitrary payload for the redeemer. +This section shows you how to perform a token swap using the Mayan Swift route. You will define a helper function to configure the source and destination chain signers. - --- +Then, you'll create a script that initiates a transfer on Ethereum, uses the Mayan Swift resolver to find valid routes, sends the transaction, and completes the transfer on Solana. - `maxFee` ++"uint128"++ +1. Open `helper.ts` and define the `getSigner` utility function to load private keys, instantiate signers for Ethereum and Solana, and return the signers along with the Wormhole-formatted address: - The maximum fee the user wants to pay to execute a fast transfer. + ```ts title="src/helpers.ts" + import { + Chain, + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, +} from '@wormhole-foundation/sdk-connect'; +import { getEvmSignerForKey } from '@wormhole-foundation/sdk-evm'; +import { getSolanaSigner } from '@wormhole-foundation/sdk-solana'; - --- +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (MAINNET_ETH_PRIVATE_KEY, MAINNET_SOL_PRIVATE_KEY) + * must be loaded securely beforehand, for example via a keystore, + * secrets manager, or environment variables (not recommended). + */ +// Define Transfer Interface +export interface SignerContext { + signer: Signer; + address: ChainAddress; +} + +export async function getSigner( + chain: ChainContext +): Promise> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + switch (platform) { + case 'Solana': + signer = await getSolanaSigner( + await chain.getRpc(), + getEnv('MAINNET_SOL_PRIVATE_KEY') + ); + break; + case 'Evm': + signer = await getEvmSignerForKey( + await chain.getRpc(), + getEnv('MAINNET_ETH_PRIVATE_KEY') + ); + break; + default: + throw new Error('Unrecognized platform: ' + platform); + } + + return { + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` + +2. In `swap.ts`, add the following script, which will handle all of the logic required to perform the token swap: + + ```ts title="src/swap.ts" + import { Wormhole, routes } from '@wormhole-foundation/sdk-connect'; +import { EvmPlatform } from '@wormhole-foundation/sdk-evm'; +import { SolanaPlatform } from '@wormhole-foundation/sdk-solana'; +import { MayanRouteSWIFT } from '@mayanfinance/wormhole-sdk-route'; +import { getSigner } from './helpers'; + +(async function () { + // Setup + const wh = new Wormhole('Mainnet', [EvmPlatform, SolanaPlatform]); + + const sendChain = wh.getChain('Ethereum'); + const destChain = wh.getChain('Solana'); + + // To transfer native ETH on Ethereum to native SOL on Solana + const source = Wormhole.tokenId(sendChain.chain, 'native'); + const destination = Wormhole.tokenId(destChain.chain, 'native'); + + // Create a new Wormhole route resolver, adding the Mayan route to the default list + // @ts-ignore: Suppressing TypeScript error because the resolver method expects a specific type, + // but MayanRouteSWIFT is compatible and works as intended in this context. + const resolver = wh.resolver([MayanRouteSWIFT]); + + // Show supported tokens + const dstTokens = await resolver.supportedDestinationTokens( + source, + sendChain, + destChain + ); + console.log(dstTokens.slice(0, 5)); + + // Load signers and addresses from helpers + const sender = await getSigner(sendChain); + const receiver = await getSigner(destChain); + + // Creating a transfer request fetches token details + // since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source, + destination, + }); + + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + const bestRoute = foundRoutes[0]!; + + // Specify the amount as a decimal string + const transferParams = { + amount: '0.002', + options: bestRoute.getDefaultOptions(), + }; + + // Validate the queries route + let validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) { + console.error(validated.error); + return; + } + console.log('Validated: ', validated); + + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) { + console.error(`Error fetching a quote: ${quote.error.message}`); + return; + } + console.log('Quote: ', quote); + + // Initiate the transfer + const receipt = await bestRoute.initiate( + tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); + + await routes.checkAndCompleteTransfer( + bestRoute, + receipt, + receiver.signer, + 15 * 60 * 1000 + ); +})(); + ``` + +3. Execute the script to initiate and complete the transfer: + + ```bash + npx tsx src/swap.ts + ``` + + If successful, you’ll see terminal output like this: + +
+npx tsx src/swap.ts +Validated: { valid: true, ... } +Quote: { success: true, ... } +Initiated transfer with receipt: ... +Checking transfer state... +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: DestinationFinalized + +
+ +Congratulations! You've just completed a cross-chain token swap from Ethereum to Solana using Settlement. + +## Customize the Integration + +You can tailor the example to your use case by adjusting: + +- **Tokens and chains**: Use `getSupportedTokens()` to explore what's available. +- **Source and destination chains**: Modify `sendChain` and `destChain` in `swap.ts`. +- **Transfer settings**: Update the amount or route parameters. +- **Signer management**: Modify `src/helpers.ts` to integrate with your preferred wallet setup. + +## Next Steps + +Once you've chosen a path, follow the corresponding guide to start building: + +- [**`demo-mayanswift`**](https://github.com/wormhole-foundation/demo-mayanswift){target=_blank}: Check out the repository for the full code example. + +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/settlement/overview/ +--- BEGIN CONTENT --- +--- +title: Settlement Overview +description: Discover how Settlement enables fast, intent-based token transfers across chains using a unified system of solver auctions and integrated execution routes. +categories: Settlement, Transfer +--- + +# Settlement Overview + +Wormhole Settlement is a multichain transfer system that allows users to specify what they want to happen, such as sending or swapping tokens, without handling the execution themselves. Instead, off-chain agents called solvers compete to fulfill these user intents. + +Settlement prioritizes speed, execution quality, and reliability. Its primary route, Mayan Swift, leverages fast off-chain auctions among a curated set of solvers to achieve low-latency bridging with minimal slippage. All settlement steps remain verifiable on-chain through Wormhole messages. + +For broader use cases and protocol-level execution, Mayan MCTP provides an alternative path. It wraps Circle’s CCTP to facilitate native USDC bridging and token delivery in a single, verifiable flow. While slower due to chain finality constraints, MCTP offers a reliable mechanism for cross-chain transfers. + +## Key Features + +- **Intent-based architecture**: Users express what they want to happen (e.g., swap X for Y on chain Z), and solvers execute it. +- **Solver auctions**: Solvers compete in on-chain auctions for the right to fulfill intents, improving execution quality. +- **Fast and fallback-capable**: Combines high-speed execution with a reliable fallback path. +- **Minimal slippage**: Settlement abstracts away complex balancing operations and uses shuttle assets like USDC and tokens deployed via NTT. +- **On-chain verifiability**: Even though auctions are off-chain, all settlement steps remain verifiable on-chain via Wormhole messages. +- **Two integrated routes**: Mayan Swift for speed, Mayan MCTP for compatibility and redundancy. + +## How It Works + +At the core of Settlement are two components: + +- **Intents**: Signed transactions where a user defines what outcome they want (e.g., send USDC to another chain and receive ETH). It abstracts what the user wants, not how it should be executed. +- **Solvers**: Third-party agents that compete in auctions to fulfill these intents. They front capital, perform swaps or transfers, and receive fees in return. + +Settlement currently supports the following integrated protocols. + +### Mayan Swift + +Mayan Swift implements a traditional intent-based architecture, where solvers compete to fulfill user intents by utilizing their inventory. It offers fast execution, typically around 12 seconds. To participate, solvers must hold assets on multiple chains, which can lead to imbalances: some chains may get depleted while others accumulate excess. This requires occasional rebalancing and adds operational overhead. Despite that, Mayan Swift is ideal for high-speed transfers and benefits from open, competitive auctions that can drive down execution prices. + +The diagram below shows how Mayan Swift handles a cross-chain intent when a user wants to swap ARB on Arbitrum for WIF on Solana. Behind the scenes, the process is more involved and relies on solver-managed liquidity across both chains. + +1. **Solver initiates on Arbitrum**: Solver swaps ARB → ETH and deposits ETH into an escrow on Arbitrum. +2. **VAA emitted to Solana**: A [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} triggers the solver to release SOL on Solana, which is swapped to WIF using an aggregator. +3. **User receives WIF**: Once the user receives WIF, a second VAA is emitted to finalize the transfer and releases the ETH held in the escrow to the solver. +4. **Failure handling**: If any step fails, the ETH in escrow is either retained or returned to the user — the solver only gets paid if execution succeeds. - `deadline` ++"uint32"++ +```mermaid +sequenceDiagram + participant User + participant Solver_ARB as Solver (Arbitrum) + participant Escrow + participant Wormhole + participant Solver_SOL as Solver (Solana) + participant Aggregator - The deadline for the fast transfer auction to start. Note: This timestamp should be for the `MatchingEngine` chain (such as Solana) to avoid any clock drift issues between different blockchains. Integrators can set this value to `0` if they don't want to use a deadline. + Note over User,Aggregator: User has ARB and wants WIF -The `placeFastMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. + User->>Solver_ARB: Submit intent (ARB → WIF) + Solver_ARB->>Escrow: Swaps ARB → ETH and deposits ETH + Escrow-->>Wormhole: Emits VAA + Wormhole-->>Solver_SOL: Delivers VAA + Solver_SOL->>Aggregator: Releases SOL and swaps to WIF + Aggregator->>Solver_SOL: Receives WIF + Solver_SOL->>User: Sends WIF + User-->>Wormhole: Emits final VAA + Wormhole-->>Escrow: Confirms receipt + Escrow->>Solver_ARB: Releases ETH to solver +``` + +### Mayan MCTP + +Mayan MCTP is a fallback protocol that wraps Circle’s CCTP into the Settlement framework. It bundles USDC bridging and swaps into a single operation handled by protocol logic. This route is slower due to its reliance on chain finality. However, it provides broad compatibility and redundancy, making it useful when faster routes are unavailable or when targeting chains that aren’t supported by Swift. While typically more expensive due to protocol fees, it ensures reliable settlement when faster options are unavailable. + +## Use Cases + +- **Cross-Chain Perpetuals** + + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Provides fast token execution across chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch live prices and manage position state across chains. + +- **Bridging Intent Library** + + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Handles user-defined bridge intents. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Triggers cross-chain function calls. -### Market Order +- **Multichain Prediction Markets** -The `placeMarketOrder` function is a _wait-for-full-finality_ USDC transfer with an arbitrary message payload. The Swap Layer, built on top of the Wormhole Settlement, uses this function if the auction on the matching engine for `placeFastMarketOrder` doesn't start within a specific deadline. + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Executes token flows between chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Gets market data and tracks state. + +## Next Steps + +Start building with Settlement or dive deeper into specific components: + +- **[Get Started with Settlement](/docs/products/settlement/get-started/)**: Follow a hands-on demo using Mayan Swift. +- **[Architecture Documentation](/docs/products/settlement/concepts/architecture/)**: Explore the Settlement architecture and components. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/token-bridge/concepts/transfer-flow/ +--- BEGIN CONTENT --- +--- +title: Flow of a Token Bridge Transfer +description: Learn how the Wormhole Token Bridge enables secure, cross-chain token transfers by combining token-specific logic with Wormhole's core message-passing layer. +categories: Token-Bridge, Transfer +--- -```solidity title="`placeMarketOrder` Interface" -function placeMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, -) external payable returns (uint64 sequence, uint64 protocolSequence); -``` +# Flow of a Transfer -??? interface "Parameters `placeMarketOrder()`" +## Introduction - `amountIn` ++"uint128"++ +The [Wormhole Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} enables token transfers across blockchains by combining token-specific logic with [Wormhole's core messaging layer](/docs/protocol/architecture/){target=\_blank}. Each supported chain runs its own Token Bridge contract, which manages actions like locking, burning, minting, and releasing tokens. These contracts communicate directly with Wormhole's core message-passing layer to securely transmit messages between chains. - The amount to transfer. +This guide provides a conceptual overview of the Token Bridge and its integration with the messaging layer. It outlines each step of the transfer flow and explains how different transfer types work in practice. - --- +## Transfer Flow - `targetChain` ++"uint16"++ +Cross-chain token transfers using the Token Bridge follow these steps: - Target chain ID. +1. **Initiation on the Source Chain** + The transfer begins when a user calls the Token Bridge contract on the source chain: - --- + - **Wrapped tokens**: The token is burned. + - **Original tokens**: If the token is native to the source chain, the token is locked in the contract. - `redeemer` ++"bytes32"++ +2. **Transfer Message Publication** + The Token Bridge contract invokes the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}, which emits an on-chain message event describing the transfer. - Redeemer contract address. +3. **Message Observation and Signing** + [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}—a decentralized network of validators—monitor the source chain for these message events. A supermajority (13 out of 19) signs the event to generate a [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}—a cryptographically signed attestation of the transfer. - --- + The VAA is then published to the Wormhole network. - `redeemerMessage` ++"bytes"++ +4. **VAA Submission to the Destination Chain** + The VAA must be submitted to the Token Bridge contract on the destination chain to complete the transfer. The Token Bridge contract then verifies the VAA by calling the Core Contract behind the scenes. This step can be handled in two ways: - An arbitrary payload for the redeemer. + - **Automatic**: A relayer service detects the VAA and submits it to the Token Bridge contract. + - **Manual**: The user or dApp retrieves the VAA and submits it directly to the Token Bridge contract. -The `placeMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. ---- END CONTENT --- +5. **Finalization of the Transfer on the Destination Chain** + After the VAA is verified on the destination chain, the Token Bridge contract completes the transfer: -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/solver/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement Solver -description: Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. -categories: Settlement, Transfer ---- + - **Wrapped tokens**: A wrapped representation of the original token is minted. + - **Original tokens**: If the token is native to the destination chain, the token is released to the recipient. -# Run a Wormhole Settlement Solver +Consider this example: Alice wants to send 5 ETH from Ethereum to Solana. The ETH is locked on Ethereum’s Token Bridge, and an equivalent amount of wrapped ETH is minted on Solana. The diagram below illustrates this transfer flow. -## Introduction +```mermaid +sequenceDiagram + participant Alice as Alice + participant TokenBridgeEth as Token Bridge Ethereum
(Source Chain) + participant CoreEth as Core Contract Ethereum
(Source Chain) + participant Guardians + participant TokenBridgeSol as Token Bridge Solana
(Destination Chain) + participant CoreSol as Core Contract Solana
(Destination Chain) -This page provides instructions on how to set up, configure, and run a Solver for Wormhole Settlement using the [example solver](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/update-solver-example/solver){target=\_blank}. + Alice->>TokenBridgeEth: Initiate ETH transfer
(lock ETH) + TokenBridgeEth->>CoreEth: Publish transfer message + CoreEth-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA -A Solver is an off-chain agent responsible for: + alt Automatic VAA submission + Guardians->>TokenBridgeSol: Relayer submits VAA + else Manual VAA submission + Alice->>Guardians: Retrieve VAA + Alice->>TokenBridgeSol: Submit VAA + end -- Listening to cross-chain transfer requests sent over Wormhole -- Bidding in auctions (on Solana) to fulfill each request -- Facilitating the actual cross-chain transfer by locking/burning assets on Solana and minting/unlocking them on the destination chain -- Rebalancing once the origin chain transaction finalizes and is redeemed back on Solana + TokenBridgeSol->>CoreSol: Verify VAA + CoreSol-->>TokenBridgeSol: VAA verified + TokenBridgeSol-->>Alice: Mint wrapped ETH on Solana (complete transfer) +``` -For information on how the protocol functions and its core features, please visit the [Wormhole Settlement](/docs/learn/transfers/settlement/overview/){target=\_blank} page. +Maybe Alice wants to transfer her wrapped ETH on Solana back to native ETH on Ethereum. The wrapped ETH is burned on Solana’s Token Bridge, and the equivalent 5 ETH are released on Ethereum. The diagram below illustrates this transfer flow. + +```mermaid +sequenceDiagram + participant User as Alice + participant TokenBridgeSrc as Token Bridge Solana
(Source Chain) + participant CoreSrc as Core Contract Solana
(Source Chain) + participant Guardians + participant TokenBridgeDst as Token Bridge Ethereum
(Destination Chain) + participant CoreDst as Core Contract Ethereum
(Destination Chain) + + User->>TokenBridgeSrc: Initiate transfer
(burn wrapped ETH) + TokenBridgeSrc->>CoreSrc: Publish message + CoreSrc-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA + + alt Automatic VAA submission + Guardians->>TokenBridgeDst: Relayer submits VAA + else Manual VAA submission + User->>Guardians: Retrieve VAA + User->>TokenBridgeDst: User submits VAA directly + end + + TokenBridgeDst->>CoreDst: Verify VAA + CoreDst-->>TokenBridgeDst: VAA verified + TokenBridgeDst-->>User: Release native ETH on Ethereum (Complete transfer) +``` -## Background -The Solana Matching Engine's permissionless English auction is a central component of Wormhole Settlement protocol architecture. The Matching Engine contract allows any third-party solver to interact with the matching engine to place bids or improve existing ones. The contract includes four key instructions: +## Automatic vs. Manual Transfers -1. `initialize_auction` - creates a new auction account on-chain and sets basic parameters like the auction's token mint, the amount required, and the bidding period details -2. `bid` - allows a solver to place or update a bid on the active auction -3. `finalize_auction` - following the conclusion of the auction, this instruction completes the fast transfer by sending funds to the recipient on the target chain. This instruction may call the Circle CCTP contract or release an NTT contract in the future, depending on the shuttle asset in question. Failure to execute this message within a predefined grace period may result in a penalty for the winning bidder. -4. `cancel_auction` - cancels an open auction when the auction is no longer valid or was created by mistake. The program returns all locked funds to their respective owners +The Token Bridge supports two modes of transfer, depending on whether the VAA submission step is handled automatically or manually: -These instructions work together to carry out the auction as follows: +- **Automatic**: A relayer service listens for new VAAs and automatically submits them to the destination chain. +- **Manual**: The user (or dApp) must retrieve the VAA and manually submit it to the destination chain. -- The solver transfers the bid amount to the program escrow account, which ensures they have liquidity -- With each successful call of `bid`, the program updates the auction to the new highest bidder, and the prior bid is atomically sent back to the originating solver -- The originating solver can repurpose the returned funds and use them to improve their bid -- Following the auction, the winning solver has to call an instruction on the matching engine to execute the intent +Here's a quick breakdown of the key differences: -When placing a bid, whether initial or improved, the solver must deposit the required funds plus a security deposit into the matching engine contract. In this permissionless auction, the requirement of this principal amount plus the security deposit ensures a solver's credible commitment to fulfill the transfer. Malicious actors could place hollow bids without this safeguard, undermining the auction's credibility and hindering true price discovery. +| Feature | Automatic Transfer | Manual Transfer | +|---------------------------|-----------------------------|-------------------------------------| +| Who submits the VAA? | Relayer | User or dApp | +| User Experience | Seamless, one-step | Requires manual intervention | +| Best for | End-users, simple UIs | Custom dApps, advanced control | +| Dependency | Requires relayer support | None | -If the winning solver fails to call the `finalize_auction` instruction, other competing solvers may permissionlessly 'slash' the solver by executing the instruction on their behalf and collecting a portion of the original security deposit as a reward. The remaining portion is routed to the user as compensation for the unanticipated delay. This mechanism properly incentivizes timely execution through solver redundancy and competition. +### Completing Manual Transfers -## Testnet Example Solver +The user who initiated the transfer should complete the transfer within 24 hours for manual transfers. Guardian Sets are guaranteed to be valid for at least that long. If a user waits longer, the Guardian Set may have changed between initiation and redemption, causing the VAA to be rejected. -You can clone the Wormhole [`example-liquidity-layer`](https://github.com/wormholelabs-xyz/example-liquidity-layer){target=\_blank} repository to use the included [`solver`](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/main/solver){target=\_blank} directory as an example solver to fulfill fast orders by interacting with the Matching Engine on Solana. +If this occurs, follow the [Replace Outdated Signatures in VAAs](){target=_blank} tutorial to update the VAA with signatures from the current Guardian Set. -!!!warning - This example is not optimized for performance, has only been tested on Solana devnet, and is not intended for production use. Any assumptions made in this example may not translate to mainnet. +## Token Bridge Relayer (TBR) -### Prerequisites +When completing an automatic transfer using the Token Bridge—either through [Connect](/docs/products/connect/overview/){target=\_blank} or programmatically via the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}—the Token Bridge Relayer (TBR) manages the interaction with the underlying Token Bridge contracts on [supported chains where the TBR is available](/docs/products/connect/reference/support-matrix/){target=\_blank}. -In order to build and install dependencies locally in this repo, you will need: + -- node v20.18.1 -- npmv - get started by installing `nvm` using this [installation guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating){target=\_blank} +### Flow of an Automatic Transfer via TBR -Navigate into the `solver` directory, then run the command below to set up your environment and install the node dependencies and Matching Engine package: +The flow of an automatic transfer using the TBR looks like this: -```sh -make dependencies -``` +1. **Initiation on the Source Chain** + The transfer begins when a user initiates a transfer on the source chain, which results in the TBR contract being called. -### Set up Config +2. **Prepare and Forward the Transfer** + The TBR verifies the token, encodes transfer details (relayer fee, native gas request, recipient), and forwards the transfer to the Token Bridge. -The following is an example of a `config.json` file for Solana devnet. The keys here are required for both the publisher and example solver processes. +3. **Core Messaging Layer Processes the Transfer** + The Token Bridge emits a message to the Core Contract. Guardians observe the message and produce a signed VAA attesting to the transfer. -```json title="config.json" -{ - "environment": "Testnet", - "zmqChannels": { - "fastVaa": "tcp://localhost:6001", - "finalizedVaa": "tcp://localhost:6002" - }, - "publisher": { - "log": { - "level": "info" - }, - "vaaSpy": { - "host": "localhost:7073", - "enableObservationCleanup": true, - "observationSeenThresholdMs": 1500000, - "observationCleanupIntervalMs": 500, - "observationsToRemovePerInterval": 5, - "delayedThresholdMs": 60000 - } - }, - "solver": { - "log": { - "level": "info", - "filename": "logs/solver.log" - }, - "connection": { - "rpc": "", - "maxTransactionsPerSecond": 5, - "commitment": "processed", - "addressLookupTable": "YourAddressLookupTab1eHere11111111111111111", - "matchingEngine": "mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS", - "mint": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", - "knownAtaOwners": [ - "Payer11111111111111111111111111111111111111", - "Payer11111111111111111111111111111111111112", - "Payer11111111111111111111111111111111111113" - ] - } - }, - "routerEndpoints": [ - { - "chain": "Sepolia", - "endpoint": "0xE57D917bf955FedE2888AAbD056202a6497F1882", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Avalanche", - "endpoint": "0x8Cd7D7C980cd72eBD16737dC3fa04469dcFcf07A", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "OptimismSepolia", - "endpoint": "0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "ArbitrumSepolia", - "endpoint": "0xe0418C44F06B0b0D7D1706E01706316DBB0B210E", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "BaseSepolia", - "endpoint": "0x824Ea687CD1CC2f2446235D33Ae764CbCd08e18C", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Polygon", - "endpoint": "0xa098368AaaDc0FdF3e309cda710D7A5f8BDEeCD9", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - } - ] -} -``` +4. **Off-Chain Relayer Observes the VAA** -The rollback risks and offer edges configured in the sample config are arbitrary placeholders. You should use historical data and your risk tolerance, to determine appropriate values for your project. + An off-chain relayer verifies the destination chain and token registration and then prepares to complete the transfer. -### Listen to Activity +5. **Relayer Computes Native Drop-Off and Submits the VAA** -The example solver listens to attested Wormhole messages (VAAs) published on the Wormhole Guardian gossip network. To listen to this gossip network and run the VAA publisher, run the command below. Docker compose is used to listen to the Pyth Beacon and start the [`publishActivity`](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/publishActivity.ts){target=\_blank} process. + The relayer queries the destination TBR for the native gas amount, includes it in the transaction, and submits the signed VAA. -```sh -NETWORK=testnet CONFIG=path/to/config.json make run-publisher -``` +6. **TBR Validates and Completes the Transfer** + + The destination TBR validates the VAA by invoking the Token Bridge contract, confirms it's from a registered TBR, verifies the token and native gas request, and then takes custody of the tokens. -You should see output resembling: +6. **Asset Distribution on the Destination Chain** -
- Start logging with info level. - 2025-01-21 16:38:28.145 [publisher] info: Environment: Testnet - 2025-01-21 16:38:36.631 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33635, vaaTime=1737499116 - 2025-01-21 16:38:51.044 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33637, vaaTime=1737499130 - 2025-01-21 16:40:24.890 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33639, vaaTime=1737499224 -
+ The TBR sends the remaining tokens and native gas to the user, pays the off-chain relayer fee, and refunds any excess native tokens. -To set up the Pyth Beacon (which is run using make `run-publisher`), you may need to increase the UDP buffer size for the OS: +The following diagram illustrates the key steps on the source chain during a transfer: -=== "Linux" +```mermaid +sequenceDiagram + participant User + participant SourceTBR as Source Chain TBR + participant SourceTB as Source Chain Token Bridge + participant Messaging as Core Messaging Layer - ```sh - sudo sysctl -w net.core.rmem_max=2097152 - sudo sysctl -w net.core.rmem_default=2097152 - ``` + User->>SourceTBR: Initiate transfer (token,
recipient, fees, native gas) + SourceTBR->>SourceTB: Forward transfer (burn or lock tokens) + SourceTB->>Messaging: Publish transfer message +``` -=== "MacOS" +Once the core messaging layer processes the transfer, the destination chain handles completion as shown below: + +```mermaid +sequenceDiagram + participant Messaging as Core Messaging Layer + participant Relayer as Off-chain Relayer + participant DestTBR as Destination Chain TBR + participant DestTB as Destination Chain
Token Bridge + participant DestUser as User
(Destination Chain) + + Messaging->>Relayer: Emit signed VAA for transfer + Relayer->>Relayer: Verifies destination chain and token registration + Relayer->>DestTBR: Query native gas amount + Relayer->>DestTBR: Submit signed VAA + DestTBR->>DestTB: Validate VAA + DestTBR->>DestTBR: Take custody of tokens + DestTBR->>DestUser: Send tokens (after fees & native gas) + DestTBR->>Relayer: Pay relayer fee & refund excess +``` - ```sh - sudo sysctl -w net.inet.udp.recvspace=2097152 - ``` +## Next Steps -### Running the Example Solver +Now that you’ve seen how a transfer works try both types yourself to experience the full process: -Using the same config for your publisher, run the example solver with the command below. +- [Get Started with Token Bridge](/docs/products/token-bridge/get-started/){target=\_blank} +--- END CONTENT --- -```sh -CONFIG=path/to/config.json make run-solver -``` +Doc-Content: https://wormhole.com/docs/products/token-bridge/faqs/ +--- BEGIN CONTENT --- +--- +title: Token Bridge FAQs +description: Find answers to common questions about the Wormhole Token Bridge, including managing wrapped assets and understanding gas fees. +categories: Token-Bridge, Transfer +--- -It is recommended you write log output to a file so errors can be tracked. The example config above specifies an example log filename. +# FAQs -This process reads the following environment variables: +## Can ownership of wrapped tokens be transferred from the Token Bridge? -```sh -SOLANA_PRIVATE_KEY_1= -SOLANA_PRIVATE_KEY_2= -SOLANA_PRIVATE_KEY_3= -SOLANA_PRIVATE_KEY_4= -SOLANA_PRIVATE_KEY_5= -``` +No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. -At least one of these environment variables must be defined as a keypair encoded in base64 format. These payers must have SOL to send transactions on Solana devnet. If they need funds, they can request them from the [Solana devnet faucet](https://faucet.solana.com/){target=\_blank}. + - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself + - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge -The example solver assumes that these payers own USDC Associated Token Accounts(ATAs), which will be used to fulfill fast transfers. These ATAs must be funded with Solana Devnet USDC. If your ATAs need funds, request some at the [Circle testnet faucet](https://faucet.circle.com/){target=\_blank}. +The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. -Wallets and their corresponding ATA will be disabled if there are insufficient funds to pay for transactions or fulfill fast transfers. These constraints can be modified using the `updatePayerMinimumLamports` and `updateTokenMinimumBalance` methods. +Relevant contracts: -An address lookup table is required to execute some transactions. Use the command below to create one. + - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} + - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} + - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} -```sh -CONFIG=path/to/config.json make create-lut -``` +## How do I update the metadata of a wrapped token? -`SOLANA_PRIVATE_KEY_1` must be defined for this script to work. +Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. -The example solver has the following toggles depending on which orders you want to fulfill: +## How do I calculate the current gas costs for Ethereum Mainnet VAA verification? -- `enableCctpOrderPipeline()` -- `enableLocalOrderPipeline()` -- `enablePlaceInitialOffer()` -- `enableImproveOffer()` +You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. -See the comments in [runExampleSolver](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/runExampleSolver.ts){target=\_blank} for more information. +## How can I update my wrapped token image on Solscan? -This example solver does NOT do the following: +Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. -- Discriminate between the CCTP source networks. You must add logic to determine whether you want to constrain fulfilling orders from specific networks. This solver will try to fulfill all orders as long as `enableCctpOrderPipeline()` is called -- Discriminate among fulfillment sizes. No logic determines how small or large fast order transfer sizes should be. This solver will try to fulfill anything as long as your balance can handle it -- Add auctions to auction history. We recommend that after settling a complete auction (one that you have won), you write the auction pubkey to a database and have a separate process to add auction history entries to reclaim rent from these auction accounts. The auction history time delay is two hours after the VAA timestamp. This example does not prescribe any specific database, so add whichever you want +To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/token-bridge/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/guides/token-bridge-contracts/ --- BEGIN CONTENT --- --- title: Get Started with Token Bridge @@ -7113,20 +7526,20 @@ description: Learn how to integrate Wormhole's Token Bridge for seamless multich categories: Token-Bridge, Transfer --- -# Token Bridge +# Interact with Token Bridge Contracts ## Introduction -Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. +Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/protocol/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. -This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} page in the Learn section. +This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} page in the Learn section. ## Prerequisites To interact with the Wormhole Token Bridge, you'll need the following: -- [The address of the Token Bridge contract](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers +- [The address of the Token Bridge contract](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers ## How to Interact with Token Bridge Contracts @@ -7377,263 +7790,89 @@ For a deeper understanding of the Token Bridge implementation and to review the ## Portal Bridge A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. - -## FAQs - -### Can ownership of wrapped tokens be transferred from the Token Bridge? - -No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. - - - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself - - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge - -The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. - -Relevant contracts: - - - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} - - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} - - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} - -### How do I update the metadata of a wrapped token? - -Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. - -### How do I calculate the current gas costs for Ethereum Mainnet VAA verification? - -You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. - -### How can I update my wrapped token image on Solscan? - -Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. - -To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/tutorials/connect/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect Tutorials -description: Enable cross-chain connectivity with Wormhole Connect. Learn integration and simplify user experiences across multiple blockchains. -categories: Connect, Transfer ---- - -# Connect - -Wormhole Connect makes it simple to link your application to multiple blockchain ecosystems. These tutorials will teach you how to integrate Connect into your projects, streamline cross-chain interactions, simplify user onboarding, and deliver a smoother overall experience. - -## Tutorials - -
- -- :octicons-repo-16:{ .lg .middle } **Integrate Connect into a React DApp** - - --- - - Learn how to incorporate Wormhole Connect into a React application. This step-by-step tutorial guides you through enabling cross-chain token transfers and interactions, bridging assets between networks, and enhancing the user experience with streamlined blockchain connectivity. - - [:custom-arrow: Start building](/docs/tutorials/connect/react-dapp/) - -
- -## Additional Resources - -
- -- :octicons-tools-16:{ .lg .middle } **Connect** - - --- - - Get deeper insights into setting up and customizing Wormhole Connect. Explore advanced guides, best practices, and configuration tips to streamline your cross-chain integrations. - - [:custom-arrow: Learn more](/docs/build/transfers/connect/) - -
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/connect/react-dapp/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/overview/ --- BEGIN CONTENT --- --- -title: Integrate Connect into a React DApp Tutorial -description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. -categories: Connect, Transfer +title: Token Bridge Overview +description: With Wormhole Token Bridge, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Token-Bridge, Transfer --- -# Integrate Connect into a React DApp - -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} - -## Introduction - -In this tutorial, we’ll explore how to integrate [Wormhole Connect](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank} to enable cross-chain token transfers and interactions. Wormhole Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Wormhole Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. - -While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any blockchain supported by Wormhole. In this example, we’ll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. - -## Prerequisites - -To get started with Wormhole Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. -Before starting this tutorial, ensure you have the following: - -- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine -- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use -- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} -- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees - -## Set Up Connect for Sui Transfers - -### Create a React Project - -Start by setting up your React app: - -1. Open your terminal and run the following command to create a new React app: - - ```bash - npx create-react-app connect-tutorial - ``` - -2. Navigate into the project directory: - - ```bash - cd connect-tutorial - ``` - -### Install Wormhole Connect - -Next, install the Wormhole Connect package as a dependency by running the following command inside your project directory: +# Token Bridge Overview -```bash -npm install @wormhole-foundation/wormhole-connect -``` - -### Integrate Connect into the Application - -Now, we need to modify the default `App.js` file to integrate Wormhole Connect. We are going to use [version V1.0](/docs/build/transfers/connect/upgrade/){target=\_blank}, make sure to check which version of connect you are using. Open `src/App.js` and replace the content with the following code: - -=== "JavaScript" - - ```js - import logo from './logo.svg'; - import './App.css'; - import WormholeConnect from '@wormhole-foundation/wormhole-connect'; - - const config = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], - }; - - function App() { - return ; - } - - export default App; - ``` - -=== "TypeScript" +The Token Bridge is a Wormhole module for bridging wrapped tokens across various blockchain networks. Locking assets on one network and minting corresponding wrapped tokens on another facilitates secure, efficient, and composable multichain token movement. - ```ts - import './App.css'; - import WormholeConnect, { - WormholeConnectConfig, - WormholeConnectTheme, - } from '@wormhole-foundation/wormhole-connect'; +This overview covers Token Bridge's main features, general processes, and possible next steps to begin building a cross-chain application. - function App() { - const config: WormholeConnectConfig = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], +## Key Features - ui: { - title: 'SUI Connect TS Demo', - }, - }; +Token Bridge is built to solve interoperability problems in multichain token transfers. Key features include: - const theme: WormholeConnectTheme = { - mode: 'dark', - primary: '#78c4b6', - }; +- **Interoperability**: Transfer standards-compliant tokens (e.g., ERC-20, SPL) across over 30 [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank}. +- **Lock-and-mint mechanism**: Mint wrapped tokens backed 1:1 by locked assets on the source chain. +- **Preserved metadata**: Ensure that token properties like name, symbol, and decimals persist across chains. +- **Transfer with payload**: Attach arbitrary data to token transfers, enabling the triggering of specific actions. +- **Decentralized security**: Verified by the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank}, ensuring cross-chain consistency and message authenticity. - return ; - } +## How It Works - export default App; - ``` +The Token Bridge provides a reliable foundation for multichain interoperability at scale. The transfer process follows these key steps: -- Set `network` to `testnet` - this ensures that Wormhole Connect uses the testnet environment -- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche +1. **Attestation**: The token’s metadata (e.g., symbol, name, decimals) is registered on the destination chain. This step is only required once per token. +2. **Locking**: On the source chain, the native token is locked in a custody account. +3. **Message emission**: The [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} verifies and emits a [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +4. **Verification**: The VAA is submitted and verified on the destination chain to confirm authenticity. +5. **Minting**: A wrapped version of the token is minted (or the native token is released) to the recipient on the destination chain. -### Customize Wormhole Connect +This diagram showcases a simplified flow of Alice bridging ETH from Ethereum to her account on Solana. -To further customize Wormhole Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Wormhole Connect Configuration guide](/docs/build/transfers/connect/configuration/#introduction){target=\_blank}. +```mermaid +sequenceDiagram + participant Alice + participant Ethereum + participant GuardianNetwork + participant Solana -### Run the Application + Alice->>Ethereum: Lock ETH in Token Bridge contract + Ethereum->>GuardianNetwork: Emit transfer message + GuardianNetwork->>GuardianNetwork: Verify and sign message -Make sure you’re in the root directory of your React app, and run the following command to start the application: + GuardianNetwork->>Solana: Submit signed message + Solana->>Solana: Verify message and mint wrapped ETH (WETH) -```bash -npm start + Solana->>Alice: Deliver wrapped ETH on Solana ``` -Now your React app should be up and running, and Wormhole Connect should be visible on `http://localhost:3000/`. You should see the Wormhole Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. - -## Transfer Tokens from Sui to Fuji - -Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. - -To transfer tokens from Sui to Fuji in the Wormhole Connect interface: +For a more in-depth understanding of how the Token Bridge works, see the [Flow of a Transfer](/docs/products/token-bridge/concepts/transfer-flow/){target=\_blank} page. -1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer -2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network -3. Enter the amount of SUI tokens you wish to transfer - - ![](/docs/images/tutorials/connect/react-dapp/connect-1.webp) - -4. Choose to view other routes - - ![](/docs/images/tutorials/connect/react-dapp/connect-2.webp) - -5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) - - !!! note - It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. - - ![](/docs/images/tutorials/connect/react-dapp/connect-3.webp) - -6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain - - ![](/docs/images/tutorials/connect/react-dapp/connect-4.webp) +## Use Cases -7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet - - ![](/docs/images/tutorials/connect/react-dapp/connect-5.webp) - -Once the transaction has been submitted, Wormhole Connect will display the progress of the transfer. Monitor the status until you’re prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. - -## Claim Tokens on Fuji - -After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. - -![](/docs/images/tutorials/connect/react-dapp/connect-6.webp) +Here are key use cases that highlight the power and versatility of the Token Bridge. -Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. +- **Multichain Rewards and Token Utility in Decentralized Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -![](/docs/images/tutorials/connect/react-dapp/connect-7.webp) + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Transfer tokens between chains. + - [**Messaging**](/docs/products/messaging/overview/): Facilitate the distribution and claiming processes of rewards. -## Resources +- **Tokenized Gaming Rewards** -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Wormhole Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Handle the underlying lock-and-mint logic securely. + - [**Connect**](/docs/products/connect/overview/): Provide a user-friendly way to move game tokens across chains. -## Conclusion +- **Multichain DeFi Arbitrage** -In this tutorial, you’ve gained hands-on experience with integrating Wormhole Connect to enable cross-chain token transfers. You’ve learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Enables rapid and secure movement of DeFi assets. + - [**Connect**](/docs/products/connect/overview/): Provides a UI widget to onboard users and facilitate seamless multichain swaps within DeFi aggregator platforms. -By following these steps, you've learned how to: +## Next Steps -- Set up a React project tailored for cross-chain transfers -- Install and configure Wormhole Connect to support multiple blockchains -- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers -- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks +If you are looking for more guided practice, take a look at: -With these tools and knowledge, you’re now equipped to build powerful cross-chain applications using Wormhole Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/): Perform token transfers using the Token Bridge, including manual and automatic transfers. +- [**Complete Token Transfer Flow**](/docs/products/token-bridge/tutorials/transfer-workflow/): Build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains. +- [**Create Multichain Tokens**](/docs/products/token-bridge/tutorials/multichain-token/): Craft a multichain token using Wormhole's Portal Bridge. --- END CONTENT --- ## Basics Concepts [shared: true] @@ -7650,2013 +7889,2469 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary - -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - -## Chain ID - -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. - -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. - -## Consistency Level - -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. - -## Delivery Provider - -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. - -## Emitter - -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - -## Finality +# Get Started with Messaging -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Guardian +## Prerequisites -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +Before you begin, ensure you have the following: -## Guardian Network +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +## Configure Your Messaging Environment -## Guardian Set +1. Create a directory and initialize a Node.js project: -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -## Heartbeat +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Observation + ```bash + npx tsc --init + ``` -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + Make sure your `tsconfig.json` includes the following settings: -## Relayer + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A relayer is any process that delivers VAAs to a destination. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Sequence + ```bash + npm install @wormhole-foundation/sdk + ``` -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. +5. Create a new file named `main.ts`: -## Spy + ```bash + touch main.ts + ``` -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; -## VAA +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Validator + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. ---- END CONTENT --- + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ ---- BEGIN CONTENT --- ---- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics ---- + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); -# Infrastructure Components + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); -## Get Started + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Start here for an overview of Wormhole architecture components and security mechanisms: + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); -
+ // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -- :octicons-book-16:{ .lg .middle } **Architecture Overview** + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; - --- + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -- :octicons-book-16:{ .lg .middle } **Security** +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` - --- + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +2. Run the script using the following command: - [:custom-arrow: Learn About Security](/docs/learn/security/) + ```bash + npx tsx main.ts + ``` + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- +
-## Explore Components +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +## Next Steps -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- -## Next Steps +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +categories: Basics +--- -
+# Get Started with Core Contracts -- :octicons-book-16:{ .lg .middle } **Messaging Components** +## Introduction - --- +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** +## Prerequisites - --- +To interact with the Wormhole Core Contract, you'll need the following: - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +## How to Interact with Core Contracts -
---- END CONTENT --- +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -# Architecture +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -## Overview +### Sending Messages -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +=== "EVM" -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: + ??? interface "Parameters" - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -## On-Chain Components + --- -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -## Off-Chain Components + --- -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -## Next Steps + ??? interface "Returns" -
+ `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -- :octicons-book-16:{ .lg .middle } **Core Contracts** + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); - --- +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. +// Check fee and send parameters - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -- :octicons-tools-16:{ .lg .middle } **Core Messaging** +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); - --- +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +=== "Solana" -
---- END CONTENT --- + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -# Core Contracts + ??? interface "Parameters" -## Introduction + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -## Key Functions + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -Key functions of the Wormhole Core Contract include the following: + ??? child "Type `PostMessage<'info>`" -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` -## How the Core Contract Works + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. + --- -The following describes the role of the Wormhole Core Contract in message transfers: + `batch_id` ++"u32"++ + + An identifier for the message batch. -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions + --- + + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. + --- -### Message Submission + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" + + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -### Message Reception +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -## Multicast +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. +### Receiving Messages -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. +The way a message is received and handled depends on the environment. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. +=== "EVM" -## Next Steps + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -
+ ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + ??? interface "Parameters" - --- + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + ??? interface "Returns" - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + ??? child "Struct `VM`" - --- + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -
---- END CONTENT --- + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Example" -## Guardian + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + // Perform safety checks here -Guardians fulfill their role in the messaging protocol as follows: + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state + // Your custom application logic here +} + ``` -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -## Guardian Network +=== "Solana" -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -The Guardian Network is designed to help Wormhole deliver on five key principles: + Retrieve the raw message data: -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -The following sections explore each principle in detail. + ??? interface "Example" -### Decentralization + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -Two common approaches to decentralization have notable limitations: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +#### Validating the Emitter -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -To answer that, consider these key constraints and design decisions: +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -### Modularity +await tx.wait(); +``` -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +#### Additional Checks -### Chain Agnosticism +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -### Scalability +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +## Source Code References -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -### Upgradeable +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -Wormhole is designed to adapt and evolve in the following ways: +# Wormhole Relayer -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +## Introduction -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -## Next Steps +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -
+## Get Started with the Wormhole Relayer -- :octicons-book-16:{ .lg .middle } **Relayers** +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. - --- +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
- [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +### Wormhole Relayer Interfaces -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: - --- +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +## Interact with the Wormhole Relayer - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -
---- END CONTENT --- +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -# Relayers +Your initial set up should resemble the following: -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -There are three primary types of relayers discussed: +contract Example { + IWormholeRelayer public wormholeRelayer; -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +### Send a Message -## Fundamentals +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -Key characteristics of VAAs include: +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -- Public emission from the Guardian Network +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -- Authentication through signatures from the Guardian Network +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -- Verifiability by any entity or any Wormhole Core Contract +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -Keep in mind the following security considerations around relayers: +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +### Receive a Message -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -## Client-Side Relaying +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +## Delivery Guarantees -### Key Features +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -### Implementation +## Delivery Statuses -Users themselves carry out the three steps of the cross-chain process: +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -1. Perform an action on chain A +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -2. Retrieve the resulting VAA from the Guardian Network +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -3. Perform an action on chain B using the VAA +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -### Considerations +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -- Users must sign all required transactions with their own wallet +## Other Considerations -- Users must have funds to pay the transaction fees on every chain involved +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- The user experience may be cumbersome due to the manual steps involved +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -## Custom Relayers +## Track the Progress of Messages with the Wormhole CLI -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +=== "Mainnet" -### Key Features + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +=== "Testnet" -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +## Step-by-Step Tutorial -### Implementation +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -### Considerations +# Messaging Overview -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -- Development work and hosting of relayers are required +## Key Features -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +## How It Works -## Wormhole Relayers +The messaging flow consists of several core components: -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -### Key Features +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +## Use Cases -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Implementation +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -The Wormhole relayer integration involves two key steps: + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -### Considerations +- **Gas Abstraction** -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -- All computations are performed on-chain +- **Bridging Intent Library** -- Potentially less gas-efficient compared to custom relayers + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- Support may not be available for all chains + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. ## Next Steps -
+Follow these steps to work with Wormhole Messaging: -- :octicons-book-16:{ .lg .middle } **Spy** +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- - --- +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +# Products - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. - --- +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +## Transfer Products - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods - --- +
- Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +::spantable:: - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | + +::end-spantable::
---- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ ---- BEGIN CONTENT --- ---- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -categories: Basics ---- +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: -# Spy +
-In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. +## Bridging UI -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. -## Key Features +## Real-time Data -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. -## Integrator Use Case +## Multichain Governance -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ +--- BEGIN CONTENT --- +--- +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +categories: Basics +--- -## Observable Message Categories +# Glossary -A Spy can access the following categories of messages shared over the gossip protocol: +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +## Chain ID - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +## Consistency Level -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +## Delivery Provider -## Additional Resources +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -
+## Emitter -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - --- +## Finality - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +## Guardian -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - --- +## Guardian Network - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +## Guardian Set -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - --- +## Heartbeat - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -
+## Observation -## Next Steps +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -
+## Relayer -- :octicons-code-16:{ .lg .middle } **Run a Spy** +A relayer is any process that delivers VAAs to a destination. - --- +## Sequence - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +## Spy -- :octicons-code-16:{ .lg .middle } **Use Queries** +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - --- +## VAA - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +## Validator -
+A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/protocol/architecture/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Architecture -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Overview -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -## VAA Format +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -The basic VAA consists of header and body components described as follows: +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - Where each `signature` is: + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## On-Chain Components -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +## Off-Chain Components -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Consistency and Finality +## Next Steps -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +
-Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- :octicons-book-16:{ .lg .middle } **Core Contracts** -## Signatures + --- -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -## Payload Types + --- -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -### Token Transfer + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +
+--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# The Wormhole Ecosystem -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Ecosystem Overview -### Attestation +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -The message format for token attestation is as follows: +## Bringing It All Together: Interoperability in Action -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. -#### Attestation Tips +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -Be aware of the following considerations when working with attestations: +## Next Steps -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +# Core Contracts -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Introduction -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer with Message +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +## Key Functions -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Key functions of the Wormhole Core Contract include the following: -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## How the Core Contract Works -### Governance +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +The following describes the role of the Wormhole Core Contract in message transfers: -#### Action Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Message Submission -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -#### Actions +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +### Message Reception -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Lifetime of a Message +## Multicast -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** - - --- - - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. - - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) - -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** - - --- - - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. - - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/introduction/ ---- BEGIN CONTENT --- ---- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. -categories: Basics ---- +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** -# Introduction to Wormhole + --- -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) + --- -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/) -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +
+--- END CONTENT --- -## What Problems Does Wormhole Solve? +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ +--- BEGIN CONTENT --- +--- +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +categories: Basics +--- -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. +## Guardian -Critical problems Wormhole addresses include: +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +Guardians fulfill their role in the messaging protocol as follows: -## What Does Wormhole Offer? +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +## Guardian Network -## What Isn't Wormhole? +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +The Guardian Network is designed to help Wormhole deliver on five key principles: -## Use Cases of Wormhole +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -Consider the following examples of potential applications enabled by Wormhole: +The following sections explore each principle in detail. -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +### Decentralization -## Explore +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -Discover more about the Wormhole ecosystem, components, and protocols: +Two common approaches to decentralization have notable limitations: -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -## Demos +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -Demos offer more realistic implementations than tutorials: +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +To answer that, consider these key constraints and design decisions: - +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -!!! note - Wormhole Integration Complete? +### Modularity - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +### Chain Agnosticism -## Supported Blockchains +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -Wormhole supports a growing number of blockchains. +### Scalability -text/supported-networks.md ---- END CONTENT --- +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -# Security +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -## Core Security Assumptions +### Upgradeable -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +Wormhole is designed to adapt and evolve in the following ways: -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -In summary: +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +## Next Steps -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +
-## Guardian Network +- :octicons-book-16:{ .lg .middle } **Relayers** -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. + --- -### Governance + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. + --- -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. -Via governance, the Guardians can: + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations +
+--- END CONTENT --- -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ +--- BEGIN CONTENT --- +--- +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +categories: Basics +--- -## Monitoring +# Relayers -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -Guardians monitor: +There are three primary types of relayers discussed: -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -## Asset Layer Protections +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +## Fundamentals -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -## Open Source +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -Wormhole builds in the open and is always open source. +Key characteristics of VAAs include: -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +- Public emission from the Guardian Network -## Audits +- Authentication through signatures from the Guardian Network -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +- Verifiability by any entity or any Wormhole Core Contract -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +Keep in mind the following security considerations around relayers: -## Bug Bounties +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +## Client-Side Relaying -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -## Learn More +### Key Features -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics ---- +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -# Get Started with Core Contracts +### Implementation -## Introduction +Users themselves carry out the three steps of the cross-chain process: -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +1. Perform an action on chain A -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +2. Retrieve the resulting VAA from the Guardian Network -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +3. Perform an action on chain B using the VAA -## Prerequisites +### Considerations -To interact with the Wormhole Core Contract, you'll need the following: +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +- Users must sign all required transactions with their own wallet -## How to Interact with Core Contracts +- Users must have funds to pay the transaction fees on every chain involved -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +- The user experience may be cumbersome due to the manual steps involved -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +## Custom Relayers -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -### Sending Messages +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +### Key Features -=== "EVM" +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - ??? interface "Parameters" +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +### Implementation - --- +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +### Considerations - --- +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +- Development work and hosting of relayers are required - ??? interface "Returns" +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +## Wormhole Relayers -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -// Check fee and send parameters +### Key Features -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +### Implementation - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +The Wormhole relayer integration involves two key steps: -=== "Solana" +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +### Considerations - ??? interface "Parameters" +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +- All computations are performed on-chain - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +- Potentially less gas-efficient compared to custom relayers - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +- Support may not be available for all chains - ??? child "Type `PostMessage<'info>`" +## Next Steps - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +
- For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +- :octicons-book-16:{ .lg .middle } **Spy** - --- + --- - `batch_id` ++"u32"++ - - An identifier for the message batch. + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - --- + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - --- + --- - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters + --- -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +
+--- END CONTENT --- -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +# Spy -### Receiving Messages +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -The way a message is received and handled depends on the environment. +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. -=== "EVM" +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +## Key Features - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - ??? interface "Parameters" +## Integrator Use Case - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - ??? interface "Returns" +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +## Observable Message Categories - ??? child "Struct `VM`" +A Spy can access the following categories of messages shared over the gossip protocol: - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events - ??? interface "Example" +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network - // Perform safety checks here +## Additional Resources - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +
- // Your custom application logic here -} - ``` +- :octicons-code-16:{ .lg .middle } **Spy Source Code** - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + --- -=== "Solana" + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} - Retrieve the raw message data: +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` + --- - ??? interface "Example" + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. + --- -#### Validating the Emitter + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: +
-```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +## Next Steps -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +
-```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +- :octicons-code-16:{ .lg .middle } **Run a Spy** -await tx.wait(); -``` + --- -#### Additional Checks + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- :octicons-code-16:{ .lg .middle } **Use Queries** -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + --- -## Source Code References + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ --- BEGIN CONTENT --- --- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics --- -# Wormhole Relayer +# Verified Action Approvals -## Introduction +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -## Get Started with the Wormhole Relayer +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +## VAA Format -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+The basic VAA consists of header and body components described as follows: -### Wormhole Relayer Interfaces +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + Where each `signature` is: -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -## Interact with the Wormhole Relayer +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -Your initial set up should resemble the following: +## Consistency and Finality -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -contract Example { - IWormholeRelayer public wormholeRelayer; +## Signatures - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) ``` -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -### Send a Message +## Payload Types -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` +### Token Transfer -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +Transferring tokens from the sending chain to the destination chain requires the following steps: -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -### Receive a Message +### Attestation -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +The message format for token attestation is as follows: -## Delivery Guarantees +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +#### Attestation Tips -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +Be aware of the following considerations when working with attestations: + +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters + +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes + +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm + +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 + +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer + +### Token Transfer with Message + +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: + +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior + +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: + +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific + +### Governance + +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). + +#### Action Structure + +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: + +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action + +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -## Delivery Statuses +#### Actions -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +## Lifetime of a Message -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -## Other Considerations +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +## Next Steps -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +
-## Track the Progress of Messages with the Wormhole CLI +- :octicons-book-16:{ .lg .middle } **Guardians** -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: + --- -=== "Mainnet" + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -=== "Testnet" +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` + --- -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -## Step-by-Step Tutorial + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/products/ +Doc-Content: https://wormhole.com/docs/protocol/introduction/ --- BEGIN CONTENT --- --- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics --- -# Products +# Introduction to Wormhole -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -## Transfer Products +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -
+This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -::spantable:: +## What Problems Does Wormhole Solve? -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -::end-spantable:: +Critical problems Wormhole addresses include: -
+- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +## What Does Wormhole Offer? -## Bridging UI +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -## Real-time Data +## What Isn't Wormhole? -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -## Multichain Governance +## Use Cases of Wormhole -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +Consider the following examples of potential applications enabled by Wormhole: -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ ---- BEGIN CONTENT --- ---- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics ---- +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. + +## Explore -# Wormhole Use Cases +Discover more about the Wormhole ecosystem, components, and protocols: -
-
+- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -## Cross-Chain Swaps and Liquidity Aggregation +## Demos -Enable seamless swaps between chains with real-time liquidity routing. +Demos offer more realistic implementations than tutorials: -
-
+- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -🛠 **Wormhole products used:** + -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +!!! note + Wormhole Integration Complete? -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -
-
+ **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +## Supported Networks by Product -
-
+Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -## Borrowing and Lending Across Chains +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -Let users borrow assets on one chain using collateral from another. +# Security -
-
+## Core Security Assumptions -🛠 **Wormhole products used:** +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +In summary: -
-
+- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -
-
+## Guardian Network -## Real-Time Price Feeds and Trading Strategies +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -Fetch price feeds across multiple chains for DeFi applications. +### Governance -
-
+Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -🛠 **Wormhole products used:** +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -
-
+Via governance, the Guardians can: +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -
-
+The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -## Asset Movement Between Bitcoin and Other Chains +## Monitoring -Enable direct BTC transfers without wrapped assets. +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -
-
+Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -🛠 **Wormhole products used:** +Guardians monitor: -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +## Asset Layer Protections -
-
+One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -
-
+To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -## Decentralized Social Platforms +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -Enable seamless communication and asset transfer across decentralized social networks. +## Open Source -
-
+Wormhole builds in the open and is always open source. -🛠 **Wormhole products used:** +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +## Audits -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -
-
+- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} + +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +## Bug Bounties -
-
+Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -## Memecoin Launchpads +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -
-
+For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -🛠 **Wormhole products used:** +## Learn More -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -
-
+# Get Started with the Solidity SDK +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -
-
+## Install the SDK -## Cross-Chain Perpetuals +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -
-
+## Key Components -🛠 **Wormhole products used:** +The following key components and features work together to make your on-chain Wormhole integration easier to build. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +??? interface "Base contracts" -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives + Leverage base contracts to send and receive messages and tokens. -
-
+ - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. +??? interface "Interfaces" -
-
+ Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -## Gas Abstraction + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +??? interface "Constants" -
-
+ Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -🛠 **Wormhole products used:** + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +## Example Usage -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -
-
+### Prerequisites +Before you begin, ensure you have the following: +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -
-
+### Set Up a Project -## Bridging Intent Library +Follow these steps to prepare your development environment: -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -
-
+ ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -🛠 **Wormhole products used:** +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +### Create and Deploy Contracts -
-
+This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. +Follow these steps to create and deploy your sender and receiver Solidity contracts: -
-
+1. Use the following example code to create `CrossChainSender.sol`: -## Multichain Prediction Markets + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -
-
+// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } + + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -🛠 **Wormhole products used:** + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +2. Use the following example code to create `CrossChainReceiver.sol`: -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; -
-
+import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -
-
+ // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -## Cross-Chain Payment Widgets + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -
-
+3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -🛠 **Wormhole products used:** +## Use Contracts to Transfer USDC -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + ```bash + touch script/transfer.ts + ``` -
-
+2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +3. Open `transfer.ts` and add the following code: + + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; + +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -
-
+ // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -## Oracle Networks + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -
-
+ // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); -🛠 **Wormhole products used:** + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); -
-
+ // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } + process.exit(0); +})(); + ``` -
-
+ This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. -## Cross-Chain Staking +3. Run the script using the following command: -Enable users to stake assets on one chain while earning rewards or securing networks on another. + ```bash + npx tsx script/transfer.ts + ``` +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! +
-
- -🛠 **Wormhole products used:** -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +## Next Steps -
-
+- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. --- END CONTENT --- ## Reference Concepts [shared: true] @@ -9672,68 +10367,7 @@ While it may not be required for all use cases, it offers a deeper technical lay ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- - -# Reference - -## Get Started - -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. - -
- -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** - - --- - - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. - - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) - -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** - - --- - - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. - - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) - -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** - - --- - - Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. - - This includes the following protocol contracts: - - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP - - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) - -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** - - --- - - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. - - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) - -
---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -9856,7 +10490,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -9911,7 +10545,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -10127,262 +10761,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -10394,7 +10862,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -10569,7 +11037,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -10650,4 +11118,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets |
+--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-files/llms-typescript-sdk.txt b/llms-files/llms-typescript-sdk.txt index 52cc3e30e..1c927c4bd 100644 --- a/llms-files/llms-typescript-sdk.txt +++ b/llms-files/llms-typescript-sdk.txt @@ -13,18 +13,325 @@ You are an AI developer assistant for Wormhole (https://wormhole.com). Your task - If unsure, respond with “Not specified in the documentation. ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/cli.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/dev-env.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/faqs.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/protocols-payloads.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/sdk-layout.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/vaas-protocols.md [type: build] -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/wormhole-sdk.md [type: build] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/cli/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/dev-env.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/faqs.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/get-started.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/protocols-payloads.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/sdk-layout.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/vaas-protocols.md [type: other] +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/sdk-reference.md [type: other] ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/toolkit/cli/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK +--- + +# Get Started with Messaging + +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. + +## Prerequisites + +Before you begin, ensure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions + +## Configure Your Messaging Environment + +1. Create a directory and initialize a Node.js project: + + ```bash + mkdir core-message + cd core-message + npm init -y + ``` + +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: + + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` + +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: + + ```bash + npx tsc --init + ``` + + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` + +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: + + ```bash + npm install @wormhole-foundation/sdk + ``` + +5. Create a new file named `main.ts`: + + ```bash + touch main.ts + ``` + +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } + + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } + + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } + + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); + + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; + + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); + + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); + + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); + + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; + + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); + + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); + + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} + +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` + + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. + +2. Run the script using the following command: + + ```bash + npx tsx main.ts + ``` + + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
+ +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages + +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. + +## Next Steps + +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/tools/cli/get-started/ --- BEGIN CONTENT --- --- title: Wormhole CLI @@ -83,7 +390,7 @@ Options: ### Subcommands -??? code "Aptos" +??? interface "Aptos" ```bash worm aptos INSERT_COMMAND @@ -113,7 +420,7 @@ Options: --version Show version number [boolean]
``` -??? code "Edit VAA" +??? interface "Edit VAA" ```bash worm edit-vaa INSERT_COMMAND @@ -142,7 +449,7 @@ Options: --guardian-secret, --gs Guardian's secret key [string] ``` -??? code "EVM" +??? interface "EVM" ```bash worm evm INSERT_COMMAND @@ -165,7 +472,7 @@ Options: --rpc RPC endpoint [string] ``` -??? code "Generate" +??? interface "Generate" ```bash worm generate INSERT_COMMAND @@ -183,7 +490,7 @@ Options: -g, --guardian-secret Guardians' secret keys (CSV) [string] [required] ``` -??? code "Info" +??? interface "Info" ```bash worm info INSERT_COMMAND @@ -211,7 +518,7 @@ Options: --version Show version number [boolean]
``` -??? code "NEAR" +??? interface "NEAR" ```bash worm near INSERT_COMMAND @@ -233,7 +540,7 @@ Options: -r, --rpc Override default rpc endpoint url [string] ``` -??? code "Parse" +??? interface "Parse" ```bash worm parse INSERT_VAA @@ -245,7 +552,7 @@ Options: --version Show version number [boolean] ``` -??? code "Recover" +??? interface "Recover" ```bash worm recover INSERT_DIGEST INSERT_SIGNATURE @@ -258,7 +565,7 @@ Options: --version Show version number [boolean] ``` -??? code "Status" +??? interface "Status" ```bash worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH @@ -331,7 +638,7 @@ Options: --version Show version number [boolean] ``` -??? code "Submit" +??? interface "Submit" ```bash worm submit INSERT_VAA @@ -410,7 +717,7 @@ Options: [boolean] [default: false] ``` -??? code "Sui" +??? interface "Sui" ```bash worm sui INSERT_COMMAND @@ -439,7 +746,7 @@ Options: --version Show version number [boolean] ``` -??? code "Transfer" +??? interface "Transfer" ```bash worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK @@ -564,7 +871,7 @@ Options: --rpc RPC endpoint [string] ``` -??? code "Verify VAA" +??? interface "Verify VAA" ```bash worm verify-vaa INSERT_VAA, INSERT_NETWORK @@ -575,10 +882,9 @@ Options: -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] ``` - ## Examples -### VAA generation +### Generate a VAA Use `generate` to create VAAs for testing. For example, use the following command to create an NFT bridge registration VAA: @@ -602,7 +908,7 @@ worm generate attestation --emitter-chain ethereum \ --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 ``` -### VAA parsing +### Parse a VAA Use `parse` to parse a VAA into JSON: @@ -650,7 +956,7 @@ payload: { } ``` -### Submitting VAAs +### Submit VAAs Use `submit` to submit a VAA to a chain. It first parses the VAA and determines the destination chain and module. For example, a contract upgrade contains both the target chain and module, so the only required argument is the network moniker (`mainnet` or `testnet`): @@ -679,7 +985,7 @@ worm submit $(cat guardian-upgrade.txt) --network mainnet --chain celo The VAA payload type (Guardian set upgrade) specifies that this VAA should go to the core bridge, and the tool directs it there. -### Getting Info +### Fetch Contract Information To get info about a contract (only EVM supported at this time), use the following command: @@ -762,8 +1068,6 @@ Running this command generates the following output: } ``` -### Additional Info Examples - You can get the contract address for a module as follows: ```bash @@ -776,6 +1080,8 @@ To get the contract address for `NFTBridge` on BSC Mainnet, for example, you can worm info contract mainnet bsc NFTBridge ``` +### Fetch Chain Information + You can get the RPC address for a chain as follows: ```bash @@ -789,7 +1095,7 @@ worm info rpc mainnet bsc ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/dev-env/ +Doc-Content: https://wormhole.com/docs/tools/dev-env/ --- BEGIN CONTENT --- --- title: Local Dev Environment @@ -803,7 +1109,7 @@ Developers building for smart contract integration will want to set up a develop ## Tooling Installation -The [Wormhole CLI Tool](/docs/build/toolkit/cli/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/build/start-building/supported-networks/){target=\_blank}. +The [Wormhole CLI Tool](/docs/tools/cli/get-started/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/products/reference/supported-networks/){target=\_blank}. ## Development Stages @@ -821,7 +1127,7 @@ Relying on native tools when possible allows for more rapid prototyping and iter ### Integration -For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/build/start-building/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. +For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/products/reference/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. !!! note Variation in host environments causes unique issues, and the computational intensity of multiple simultaneous local validators can make setting them up difficult or time-consuming. You may prefer Testnets for the simplest integration testing. @@ -839,7 +1145,7 @@ If you'd like to set up a local validator environment, follow the setup guide fo ### Testnet -When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: +When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: ```text https://api.testnet.wormholescan.io @@ -847,14 +1153,14 @@ https://api.testnet.wormholescan.io ### Mainnet -The Mainnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: +The Mainnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: ```text https://api.wormholescan.io ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/faqs/ +Doc-Content: https://wormhole.com/docs/tools/faqs/ --- BEGIN CONTENT --- --- title: Toolkit FAQs @@ -904,148 +1210,460 @@ To manually submit a VAA (Verifiable Action Approval) to a destination chain, fo 3. **Submit the VAA through Etherscan (for EVM chains)** - once the VAA is in hex format, go to the [Etherscan UI](https://etherscan.io/){target=\_blank} and submit it through the [`TokenBridge`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} contract’s method (such as the `CompleteTransfer` function or `CompleteTransferWithPayload`) - - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/build/reference/contract-addresses/){target=\_blank} section + - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/products/reference/contract-addresses/){target=\_blank} section - Interact with the smart contract through the Etherscan UI by pasting the hex-encoded VAA into the appropriate field Following these steps, you can manually submit a VAA in the proper format to a destination chain. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/get-started/ --- BEGIN CONTENT --- --- -title: Wormhole SDK -description: The Wormhole SDK provides tools for cross-chain communication, token bridges, and more, enabling developers to integrate with multiple blockchain environments. +title: Get Started with the TypeScript SDK +description: Follow this guide to install the Wormhole TypeScript SDK, initialize a Wormhole instance, and add the platforms your integration supports. categories: Typescript-SDK --- -# Wormhole SDK +# Get Started with the TypeScript SDK -## Get Started +## Introduction -The Wormhole SDK provides developers with essential tools for cross-chain communication, token bridges, and more. This SDK enables seamless interaction between different blockchain environments with a focus on performance and usability. +The Wormhole TypeScript SDK provides a unified, type-safe interface for building cross-chain applications. It is a foundational toolkit that supports interaction with core Wormhole protocols, including Native Token Transfers, Token Bridge, CCTP, and Settlement, giving developers a consistent API across multiple chains. -
+This guide helps you install the SDK, initialize a `Wormhole` instance to support your desired network and blockchain platforms, and return chain-specific information to verify successful initialization. -- :octicons-book-16:{ .lg .middle } **Wormhole SDK** +If you want to build more advanced integrations, such as token transfers using the Token Bridge or CCTP Bridge, skip ahead to [Next Steps](#next-steps). - --- +## Install the SDK - Learn about the core functionalities of the Wormhole SDK, including how to use its features for building cross-chain applications. +To install the Wormhole TypeScript SDK, use the following command: - [:custom-arrow: Explore the SDK](/docs/build/toolkit/typescript-sdk/wormhole-sdk/) +```bash +npm install @wormhole-foundation/sdk +``` -- :octicons-code-16:{ .lg .middle } **Layouts** +This package combines all the individual packages to make setup easier. - --- +You can choose to install a specific set of packages as needed. For example, to install EVM-specific utilities, you can run: - Discover how to define, serialize, and deserialize data structures using the Wormhole SDK's layout system, ensuring efficient cross-chain communication. +```bash +npm install @wormhole-foundation/sdk-evm +``` - [:custom-arrow: Learn about layouts](/docs/build/toolkit/typescript-sdk/sdk-layout/) +??? example "Complete list of individually published packages" -
---- END CONTENT --- + Platform-Specific Packages -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/protocols-payloads/ ---- BEGIN CONTENT --- ---- -title: Building Protocols and Payloads -description: Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. -categories: Typescript-SDK ---- + - `@wormhole-foundation/sdk-evm` + - `@wormhole-foundation/sdk-solana` + - `@wormhole-foundation/sdk-algorand` + - `@wormhole-foundation/sdk-aptos` + - `@wormhole-foundation/sdk-cosmwasm` + - `@wormhole-foundation/sdk-sui` -# Building Protocols and Payloads + --- -## Introduction + Protocol-Specific Packages -The [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} provides a flexible and powerful system for integrating cross-chain communication into your applications. A key feature of the SDK is its ability to define protocols—modular units representing distinct functionalities—and their associated payloads, which encapsulate the data required for specific operations within those protocols. + - Core Protocol + - `@wormhole-foundation/sdk-evm-core` + - `@wormhole-foundation/sdk-solana-core` + - `@wormhole-foundation/sdk-algorand-core` + - `@wormhole-foundation/sdk-aptos-core` + - `@wormhole-foundation/sdk-cosmwasm-core` + - `@wormhole-foundation/sdk-sui-core` -This guide will help you understand how to build protocols and payloads in the SDK, covering: + - Token Bridge + - `@wormhole-foundation/sdk-evm-tokenbridge` + - `@wormhole-foundation/sdk-solana-tokenbridge` + - `@wormhole-foundation/sdk-algorand-tokenbridge` + - `@wormhole-foundation/sdk-aptos-tokenbridge` + - `@wormhole-foundation/sdk-cosmwasm-tokenbridge` + - `@wormhole-foundation/sdk-sui-tokenbridge` - - The role of protocols and payloads in cross-chain communication - - The mechanics of registering protocols and payloads using the SDK - - Best practices for creating strongly typed layouts to ensure compatibility and reliability - - Real-world examples using the `TokenBridge` as a reference implementation + - CCTP + - `@wormhole-foundation/sdk-evm-cctp` + - `@wormhole-foundation/sdk-solana-cctp` + - `@wormhole-foundation/sdk-aptos-cctp` + - `@wormhole-foundation/sdk-sui-cctp` -By the end of this guide, you’ll have a solid understanding of how to define, register, and use protocols and payloads in your projects. + - Other Protocols + - `@wormhole-foundation/sdk-evm-portico` + - `@wormhole-foundation/sdk-evm-tbtc` + - `@wormhole-foundation/sdk-solana-tbtc` -## What is a Protocol? + --- -In the Wormhole SDK, a protocol represents a significant feature or functionality that operates across multiple blockchains. Protocols provide the framework for handling specific types of messages, transactions, or operations consistently and standardized. + Utility Packages + + - `@wormhole-foundation/sdk-base` + - `@wormhole-foundation/sdk-definitions` + - `@wormhole-foundation/sdk-connect` -Examples of Protocols: - - **`TokenBridge`** - enables cross-chain token transfers, including operations like transferring tokens and relaying payloads - - **`NTT (Native Token Transfers)`** - manages native token movements across chains +## Initialize the SDK -Protocols are defined by: +Getting your integration started is simple. First, import Wormhole: - - **A `name`** - a string identifier (e.g., `TokenBridge`, `Ntt`) - - **A set of `payloads`** - these represent the specific actions or messages supported by the protocol, such as `Transfer` or `TransferWithPayload` +```ts +import { wormhole } from '@wormhole-foundation/sdk'; -Each protocol is registered in the Wormhole SDK, allowing developers to leverage its predefined features or extend it with custom payloads. +import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; +import algorand from '@wormhole-foundation/sdk/algorand'; +import aptos from '@wormhole-foundation/sdk/aptos'; +import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { getSigner } from './helpers/index.js'; -## What is a Payload? +(async function () { + const wh = await wormhole('Testnet', [ + evm, + solana, + aptos, + algorand, + cosmwasm, + sui, + ]); -A payload is a structured piece of data that encapsulates the details of a specific operation within a protocol. It defines the format, fields, and types of data used in a message or transaction. Payloads ensure consistency and type safety when handling complex cross-chain operations. + const ctx = wh.getChain('Solana'); -Each payload is defined as: + const rcv = wh.getChain('Algorand'); - - **A `layout`** - describes the binary format of the payload fields - - **A `literal`** - combines the protocol name and payload name into a unique identifier (e.g., `TokenBridge:Transfer`) + const sender = await getSigner(ctx); + const receiver = await getSigner(rcv); -By registering payloads, developers can enforce type safety and enable serialization and deserialization for specific protocol operations. + // Get a Token Bridge contract client on the source + const sndTb = await ctx.getTokenBridge(); -## Register Protocols and Payloads + // Send the native token of the source chain + const tokenId = Wormhole.tokenId(ctx.chain, 'native'); -Protocols and payloads work together to enable cross-chain communication with precise type safety. For instance, in the `TokenBridge` protocol: + // Bigint amount using `amount` module + const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); - - The protocol is registered under the `TokenBridge` namespace - - Payloads like `Transfer` or `AttestMeta` are linked to the protocol to handle specific operations + // Create a transaction stream for transfers + const transfer = sndTb.transfer( + sender.address.address, + receiver.address, + tokenId.address, + amt + ); -Understanding the connection between these components is important for customizing or extending the SDK to suit your needs. + // Sign and send the transaction + const txids = await signSendWait(ctx, transfer, sender.signer); + console.log('Sent: ', txids); -### Register Protocols + // Get the Wormhole message ID from the transaction + const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); + console.log('Wormhole Messages: ', whm); -Registering a protocol establishes its connection to Wormhole's infrastructure, ensuring it interacts seamlessly with payloads and platforms while maintaining type safety and consistency. + const vaa = await wh.getVaa( + // Wormhole Message ID + whm!, + // Protocol:Payload name to use for decoding the VAA payload + 'TokenBridge:Transfer', + // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available + 60_000 + ); -#### How Protocol Registration Works + // Now get the token bridge on the redeem side + const rcvTb = await rcv.getTokenBridge(); -Protocol registration involves two key tasks: + // Create a transaction stream for redeeming + const redeem = rcvTb.redeem(receiver.address.address, vaa!); - - **Mapping protocols to interfaces** - connect the protocol to its corresponding interface, defining its expected behavior across networks (`N`) and chains (`C`). This ensures type safety, similar to strong typing, by preventing runtime errors if protocol definitions are incorrect - - **Linking protocols to platforms** - specify platform-specific implementations if needed, or use default mappings for platform-agnostic protocols + // Sign and send the transaction + const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); + console.log('Sent: ', rcvTxids); -For example, here's the `TokenBridge` protocol registration: + // Now check if the transfer is completed according to + // the destination token bridge + const finished = await rcvTb.isTransferCompleted(vaa!); + console.log('Transfer completed: ', finished); +})(); +``` -```typescript -declare module '../../registry.js' { - export namespace WormholeRegistry { - interface ProtocolToInterfaceMapping { - TokenBridge: TokenBridge; - } - interface ProtocolToPlatformMapping { - TokenBridge: EmptyPlatformMap<'TokenBridge'>; - } - } -} - +Then, import each of the ecosystem [platforms](/docs/tools/typescript-sdk/sdk-reference/#platforms) that you wish to support: + +```ts +import aptos from '@wormhole-foundation/sdk/aptos'; +import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; ``` -This code snippet: +To make the [platform](/docs/tools/typescript-sdk/sdk-reference/#platforms) modules available for use, pass them to the Wormhole constructor and specify the network (`Mainnet`, `Testnet`, or `Devnet`) you want to interact with: - - Maps the `TokenBridge` protocol to its interface to define how it operates - - Links the protocol to a default platform mapping via `EmptyPlatformMap` +```ts +evm, + solana, + aptos, + algorand, + cosmwasm, + sui, + ]); +``` -You can view the full implementation in the [`TokenBridge` protocol file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L14-L70){target=\_blank}. +With a configured `Wormhole` object, you can begin to interact with these chains. -#### Platform-Specific Protocols +## Example Usage -Some protocols require platform-specific behavior. For instance, the EVM-compatible Wormhole Registry maps native addresses for Ethereum-based chains: +Follow these steps to confirm that the SDK is initialized correctly and can fetch basic chain information for your target chains. -```typescript -declare module '@wormhole-foundation/sdk-connect' { - export namespace WormholeRegistry { +### Prerequisites + +Before you begin, make sure you have the following: + + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed + - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed + +??? example "Project setup instructions" + + Use the following commands to create a TypeScript project: + + 1. Create a directory and initialize a Node.js project: + + ```bash + mkdir wh-ts-demo + cd wh-ts-demo + npm init -y + ``` + + 2. Install TypeScript, `tsx` (for running TypeScript files), Node.js type definitions, the base Wormhole SDK, and the platform-specific packages for the chains you want to interact with: + + ```bash + npm install --save-dev tsx typescript @types/node @wormhole-foundation/sdk @wormhole-foundation/sdk-evm @wormhole-foundation/sdk-solana + ``` + + 3. Create a `tsconfig.json` if you don't have one. You can generate a basic one using the following command: + + ```bash + npx tsc --init + ``` + + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` + + 4. Initialize the main `Wormhole` class to use the SDK. Create a new TypeScript file named `src/main.ts` in your project directory: + + ```bash + mkdir src + touch src/main.ts + ``` + + 5. Add the following code to initialize the SDK and use the `Wormhole` instance to return the chain ID and RPC for the chains this instance supports: + + ```ts title="src/main.ts" + import { wormhole } from '@wormhole-foundation/sdk'; +// Import specific platform modules for the chains you intend to use +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; + +async function main() { + console.log('Initializing Wormhole SDK...'); + + // Determine the network: "Mainnet", "Testnet", or "Devnet" + const network = 'Testnet'; + + // Initialize the SDK with the chosen network and platform contexts + const wh = await wormhole(network, [evm, solana]); + + console.log('Wormhole SDK Initialized!'); +} + +main().catch((e) => { + console.error('Error initializing Wormhole SDK', e); + process.exit(1); +}); + ``` + +### Fetch Chain Information + +1. Update the `main` function as follows to retrieve the chain ID and RPC for the chains your project supports: + + ```ts title="src/main.ts" + import { wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; + +async function main() { + console.log('Initializing Wormhole SDK...'); + + const network = 'Testnet'; + const wh = await wormhole(network, [evm, solana]); + + console.log('Wormhole SDK Initialized!'); + + // Example: Get a chain ID and RPC for Solana + const solanaDevnetChain = wh.getChain('Solana'); + console.log( + `Chain ID for Solana Testnet: ${solanaDevnetChain.config.chainId}` + ); + console.log(`RPC for Solana Testnet: ${solanaDevnetChain.config.rpc}`); + + // Example: Get a chain ID for Sepolia (EVM Testnet) + const sepoliaChain = wh.getChain('Sepolia'); + console.log(`Chain ID for Sepolia: ${sepoliaChain.config.chainId}`); + console.log(`RPC for Sepolia: ${sepoliaChain.config.rpc}`); +} + +main().catch((e) => { + console.error( + 'Error initializing Wormhole SDK or fetching chain information:', + e + ); + process.exit(1); +}); + ``` + +2. Run the script with the following command, replacing `INSERT_FILE_NAME` with your file name: + + ```bash + npx tsx INSERT_FILE_NAME + ``` + + You will see terminal output similar to the following: + +
+npx tsx src/main.ts +Initializing Wormhole SDK... +Wormhole SDK Initialized! +Chain ID for Solana Testnet: 1 +RPC for Solana Testnet: https://api.devnet.solana.com +Chain ID for Sepolia: 10002 +RPC for Sepolia: https://ethereum-sepolia.publicnode.com + +
+ +Congratulations! You’ve successfully installed the Wormhole TypeScript SDK and initialized a `Wormhole` instance. Consider the following options to build on what you've accomplished. + +## Next Steps + +- [Get familiar with the SDK](/docs/tools/typescript-sdk/sdk-reference/) +- [Send a multichain message](/docs/products/messaging/get-started/) +- [Transfer assets via the Token Bridge](/docs/products/token-bridge/tutorials/transfer-workflow/) +- [Transfer USDC via the CCTP Bridge](/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/) +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/protocols-payloads/ +--- BEGIN CONTENT --- +--- +title: Building Protocols and Payloads +description: Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. +categories: Typescript-SDK +--- + +# Building Protocols and Payloads + +## Introduction + +The [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} provides a flexible and powerful system for integrating cross-chain communication into your applications. A key feature of the SDK is its ability to define protocols—modular units representing distinct functionalities—and their associated payloads, which encapsulate the data required for specific operations within those protocols. + +This guide will help you understand how to build protocols and payloads in the SDK, covering: + + - The role of protocols and payloads in cross-chain communication + - The mechanics of registering protocols and payloads using the SDK + - Best practices for creating strongly typed layouts to ensure compatibility and reliability + - Real-world examples using the `TokenBridge` as a reference implementation + +By the end of this guide, you’ll have a solid understanding of how to define, register, and use protocols and payloads in your projects. + +## What is a Protocol? + +In the Wormhole SDK, a protocol represents a significant feature or functionality that operates across multiple blockchains. Protocols provide the framework for handling specific types of messages, transactions, or operations consistently and standardized. + +Examples of Protocols: + + - **`TokenBridge`** - enables cross-chain token transfers, including operations like transferring tokens and relaying payloads + - **`NTT (Native Token Transfers)`** - manages native token movements across chains + +Protocols are defined by: + + - **A `name`** - a string identifier (e.g., `TokenBridge`, `Ntt`) + - **A set of `payloads`** - these represent the specific actions or messages supported by the protocol, such as `Transfer` or `TransferWithPayload` + +Each protocol is registered in the Wormhole SDK, allowing developers to leverage its predefined features or extend it with custom payloads. + +## What is a Payload? + +A payload is a structured piece of data that encapsulates the details of a specific operation within a protocol. It defines the format, fields, and types of data used in a message or transaction. Payloads ensure consistency and type safety when handling complex cross-chain operations. + +Each payload is defined as: + + - **A `layout`** - describes the binary format of the payload fields + - **A `literal`** - combines the protocol name and payload name into a unique identifier (e.g., `TokenBridge:Transfer`) + +By registering payloads, developers can enforce type safety and enable serialization and deserialization for specific protocol operations. + +## Register Protocols and Payloads + +Protocols and payloads work together to enable cross-chain communication with precise type safety. For instance, in the `TokenBridge` protocol: + + - The protocol is registered under the `TokenBridge` namespace + - Payloads like `Transfer` or `AttestMeta` are linked to the protocol to handle specific operations + +Understanding the connection between these components is important for customizing or extending the SDK to suit your needs. + +### Register Protocols + +Registering a protocol establishes its connection to Wormhole's infrastructure, ensuring it interacts seamlessly with payloads and platforms while maintaining type safety and consistency. + +#### How Protocol Registration Works + +Protocol registration involves two key tasks: + + - **Mapping protocols to interfaces** - connect the protocol to its corresponding interface, defining its expected behavior across networks (`N`) and chains (`C`). This ensures type safety, similar to strong typing, by preventing runtime errors if protocol definitions are incorrect + - **Linking protocols to platforms** - specify platform-specific implementations if needed, or use default mappings for platform-agnostic protocols + +For example, here's the `TokenBridge` protocol registration: + +```typescript +declare module '../../registry.js' { + export namespace WormholeRegistry { + interface ProtocolToInterfaceMapping { + TokenBridge: TokenBridge; + } + interface ProtocolToPlatformMapping { + TokenBridge: EmptyPlatformMap<'TokenBridge'>; + } + } +} + +``` + +This code snippet: + + - Maps the `TokenBridge` protocol to its interface to define how it operates + - Links the protocol to a default platform mapping via `EmptyPlatformMap` + +You can view the full implementation in the [`TokenBridge` protocol file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L14-L70){target=\_blank}. + +#### Platform-Specific Protocols + +Some protocols require platform-specific behavior. For instance, the EVM-compatible Wormhole Registry maps native addresses for Ethereum-based chains: + +```typescript +declare module '@wormhole-foundation/sdk-connect' { + export namespace WormholeRegistry { interface PlatformToNativeAddressMapping { Evm: EvmAddress; } @@ -1131,7 +1749,7 @@ This implementation ensures dynamic, efficient handling of payloads at runtime. ## Integrate Protocols with Payloads -Integrating payloads with protocols enables dynamic identification through payload literals, while serialization and deserialization ensure their binary representation is compatible across chains. For more details on these processes, refer to the [Layouts page](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank}. +Integrating payloads with protocols enables dynamic identification through payload literals, while serialization and deserialization ensure their binary representation is compatible across chains. For more details on these processes, refer to the [Layouts page](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank}. ### Payload Discriminators @@ -1267,7 +1885,7 @@ While this guide focuses on the `TokenBridge` protocol, other protocols, like NT For more details, you can explore the [NTT implementation in the SDK](https://github.com/wormhole-foundation/example-native-token-transfers/blob/00f83aa215338b1b8fd66f522bd0f45be3e98a5a/sdk/definitions/src/ntt.ts){target=\_blank}. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/sdk-layout/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/sdk-layout/ --- BEGIN CONTENT --- --- title: Data Layouts @@ -1697,7 +2315,7 @@ VAAs are the backbone of Wormhole’s cross-chain communication. Each VAA is a s The Wormhole SDK organizes the VAA structure into three key components: - [**Header**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L37-L41){target=\_blank} - contains metadata such as the Guardian set index and an array of Guardian signatures - - [**Envelope**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} - includes chain-specific details such as the emitter chain, address, sequence, and [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} + - [**Envelope**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} - includes chain-specific details such as the emitter chain, address, sequence, and [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} - **Payload** - provides application-specific data, such as the actual message or operation being performed **Header layout:** @@ -1859,7 +2477,7 @@ return { In the Wormhole SDK, payloads rely on layouts to define their binary structure, ensuring consistency and type safety across protocols. Custom payloads extend this functionality, allowing developers to handle protocol-specific features or unique use cases. -To learn how to define and register payloads using layouts, refer to the [Building Protocols and Payloads](/docs/build/toolkit/typescript-sdk/protocols-payloads/){target=\_blank} page for a detailed guide. +To learn how to define and register payloads using layouts, refer to the [Building Protocols and Payloads](/docs/tools/typescript-sdk/guides/protocols-payloads/){target=\_blank} page for a detailed guide. ## Common Pitfalls & Best Practices @@ -1981,7 +2599,7 @@ For further learning and practical experience, explore the following resources: - **Layout tests repository** - for hands-on experimentation, check out this [layout package repository](https://github.com/nonergodic/layout){target=\_blank}, which provides examples and unit tests to help you better understand serialization, deserialization, and the strong typing mechanism. Running these tests locally is a great way to deepen your understanding of how layouts function in real-world scenarios --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/vaas-protocols/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/vaas-protocols/ --- BEGIN CONTENT --- --- title: VAAs and Protocols @@ -1993,12 +2611,12 @@ categories: Typescript-SDK ## Introduction -Wormhole's core functionality revolves around [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs), which are signed messages enabling secure and decentralized communication across chains. This guide focuses on their practical usage within the Wormhole ecosystem, specifically when working with protocol-specific messages in the [TypeScript](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and [Solidity](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} SDKs. +Wormhole's core functionality revolves around [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs), which are signed messages enabling secure and decentralized communication across chains. This guide focuses on their practical usage within the Wormhole ecosystem, specifically when working with protocol-specific messages in the [TypeScript](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and [Solidity](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} SDKs. For deeper insights into serialization, deserialization, and protocol design, refer to: -- [Data Layouts](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank} for serialization concepts -- [Building Protocols and Payloads](/docs/build/toolkit/typescript-sdk/protocols-payloads/){target=\_blank} for designing custom protocol messages +- [Data Layouts](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank} for serialization concepts +- [Building Protocols and Payloads](/docs/tools/typescript-sdk/guides/protocols-payloads/){target=\_blank} for designing custom protocol messages This guide will help you understand how to handle VAAs and protocol messages in off-chain and on-chain scenarios. @@ -2017,7 +2635,7 @@ The VAA's body combines the Envelope and Payload. The Wormhole Guardians signed When integrating protocols like Token Bridge or Wormhole Relayer: - The TypeScript SDK handles VAAs off-chain, focusing on deserialization, validation, and payload extraction before submission -- The Solidity SDK processes VAAs on-chain, using libraries like `VaaLib` to decode and execute protocol actions +- The Solidity SDK processes VAAs on-chain, using libraries like [`VaaLib`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/VaaLib.sol){target=\_blank} to decode and execute protocol actions ## VAAs in Protocol Contexts @@ -2039,7 +2657,7 @@ Each protocol integrates its payload format into the VAA structure, ensuring con The TypeScript SDK is designed for off-chain operations like reading, validating, and manipulating VAAs before submitting them to a chain. Developers can easily deserialize VAAs to extract protocol payloads and prepare actions such as initiating token transfers or constructing delivery instructions. -In the example below, we use the real [`envelopeLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dd6bd2463264680597519285ff559f9e92e85ca7/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} from Wormhole's TS SDK to deserialize and extract essential information like the emitter chain, sequence, and [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank}: +In the example below, we use the real [`envelopeLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dd6bd2463264680597519285ff559f9e92e85ca7/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} from Wormhole's TS SDK to deserialize and extract essential information like the emitter chain, sequence, and [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank}: ```typescript import { deserializeLayout } from '@wormhole-foundation/sdk-base'; @@ -2102,7 +2720,7 @@ contract EnvelopeParser { ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/wormhole-sdk/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/sdk-reference/ --- BEGIN CONTENT --- --- title: Wormhole TS SDK @@ -2110,14 +2728,9 @@ description: Explore Wormhole's TypeScript SDK and learn how to perform differen categories: Typescript-SDK --- -# Wormhole TypeScript SDK - -## Introduction - -The Wormhole TypeScript SDK is useful for interacting with the chains Wormhole supports and the [protocols](#protocols) built on top of Wormhole. This package bundles together functions, definitions, and constants that streamline the process of connecting chains and completing transfers using Wormhole. The SDK also offers targeted sub-packages for Wormhole-connected platforms, which allow you to add multichain support without creating outsized dependencies. - -This section covers all you need to know about the functionality and ease of development offered through the Wormhole TypeScript SDK. Take a tour of the package to discover how it helps make integration easier. Learn more about how the SDK abstracts away complexities around concepts like platforms, contexts, and signers. Finally, you'll find guidance on usage, along with code examples, to show you how to use the tools of the SDK. +# Wormhole TypeScript SDK Reference +This page covers all you need to know about the functionality offered through the Wormhole TypeScript SDK.
@@ -2125,419 +2738,135 @@ This section covers all you need to know about the functionality and ease of dev --- - Find installation instructions for both the meta package and installing specific, individual packages + Find installation instructions for both the meta package and installing specific, individual packages. - [:custom-arrow: Install the SDK](#installation) + [:custom-arrow: Install the SDK](/docs/tools/typescript-sdk/get-started/#install-the-sdk) -- :octicons-book-16:{ .lg .middle } **Concepts** +- :octicons-code-square-16:{ .lg .middle } **TSdoc for SDK** --- - Understand key concepts and how the SDK abstracts them away. Learn more about platforms, chain context, addresses, and signers + Review the TSdoc for the Wormhole TypeScript SDK for a detailed look at available methods, classes, interfaces, and definitions. - [:custom-arrow: Explore concepts](#concepts) + [:custom-arrow: View the TSdoc on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank} -- :octicons-file-code-16:{ .lg .middle } **Usage** +- :octicons-code-square-16:{ .lg .middle } **Source Code** --- - Guidance on using the SDK to add seamless interchain messaging to your application, including code examples + Want to go straight to the source? Check out the TypeScript SDK GitHub repository. + + [:custom-arrow: View GitHub Repository](https://github.com/wormhole-foundation/wormhole-sdk-ts/){target=\_blank} - [:custom-arrow: Use the SDK](#usage) +
-- :octicons-code-square-16:{ .lg .middle } **TSdoc for SDK** +!!! warning + This package is a work in progress. The interface may change, and there are likely bugs. Please [report any issues](https://github.com/wormhole-foundation/connect-sdk/issues){target=\_blank} you find. - --- +## Concepts - Review the TSdoc for the Wormhole TypeScript SDK for a detailed look at availabel methods, classes, interfaces, and definitions +Understanding key Wormhole concepts—and how the SDK abstracts them—will help you use the tools more effectively. The following sections cover platforms, chain contexts, addresses, signers, and protocols, explaining their roles in Wormhole and how the SDK simplifies working with them. - [:custom-arrow: View the TSdoc on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank} +### Platforms - +The SDK includes `Platform` modules, which create a standardized interface for interacting with the chains of a supported platform. The contents of a module vary by platform but can include: -!!! warning - This package is a work in progress. The interface may change, and there are likely bugs. Please [report](https://github.com/wormhole-foundation/connect-sdk/issues){target=\_blank} any issues you find. +- [Protocols](#protocols) preconfigured to suit the selected platform +- Definitions and configurations for types, signers, addresses, and chains +- Helpers configured for dealing with unsigned transactions on the selected platform -## Installation +These modules expose key functions and types from the native ecosystem, reducing the need for full packages and keeping dependencies lightweight. -### Basic +??? interface "Supported platform modules" -To install the meta package using npm, run the following command in the root directory of your project: + | Platform | Installation Command | + |----------|----------------------------------------------------| + | EVM |
```@wormhole-foundation/sdk-evm```
| + | Solana |
```@wormhole-foundation/sdk-solana```
| + | Algorand |
```@wormhole-foundation/sdk-algorand```
| + | Aptos |
```@wormhole-foundation/sdk-aptos```
| + | Cosmos |
```@wormhole-foundation/sdk-cosmwasm```
| + | Sui |
```@wormhole-foundation/sdk-sui```
| -```bash -npm install @wormhole-foundation/sdk -``` + See the [Platforms folder of the TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms){target=\_blank} for an up-to-date list of the platforms supported by the Wormhole TypeScript SDK. -This package combines all the individual packages to make setup easier while allowing for tree shaking. +### Chain Context -### Advanced +`ChainContext` (from the `@wormhole-foundation/sdk-definitions` package) provides a unified interface for interacting with connected chains. It: -Alternatively, you can install a specific set of published packages individually: +- Holds network, chain, and platform configurations +- Caches RPC and protocol clients +- Exposes both platform-inherited and chain-specific methods +- Defines the core types used across the SDK: `Network`, `Chain`, and `Platform` -??? interface "`sdk-base` - exposes constants" +```ts +// Get the chain context for the source and destination chains +// This is useful to grab direct clients for the protocols +const srcChain = wh.getChain(senderAddress.chain); +const dstChain = wh.getChain(receiverAddress.chain); - ```sh - npm install @wormhole-foundation/sdk-base - ``` +const tb = await srcChain.getTokenBridge(); // => TokenBridge<'Evm'> +srcChain.getRpcClient(); // => RpcClient<'Evm'> +``` -??? interface "`sdk-definitions` - exposes contract interfaces, basic types, and VAA payload definitions" +### Addresses - ```sh - npm install @wormhole-foundation/sdk-definitions - ``` +The SDK uses the `UniversalAddress` class to implement the `Address` interface, standardizing address handling across chains. All addresses are parsed into a 32-byte format. Each platform also defines a `NativeAddress` type that understands its native format. These abstractions ensure consistent cross-chain address handling. -??? interface "`sdk-evm` - exposes EVM-specific utilities" +```ts +// It's possible to convert a string address to its Native address +const ethAddr: NativeAddress<'Evm'> = toNative('Ethereum', '0xbeef...'); - ```sh - npm install @wormhole-foundation/sdk-evm - ``` +// A common type in the SDK is the `ChainAddress` which provides +// the additional context of the `Chain` this address is relevant for +const senderAddress: ChainAddress = Wormhole.chainAddress( + 'Ethereum', + '0xbeef...' +); +const receiverAddress: ChainAddress = Wormhole.chainAddress( + 'Solana', + 'Sol1111...' +); -??? interface "`sdk-evm-tokenbridge` - exposes the EVM Token Bridge protocol client" +// Convert the ChainAddress back to its canonical string address format +const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' - ```sh - npm install @wormhole-foundation/sdk-evm-tokenbridge - ``` +// Or if the ethAddr above is for an emitter and you need the UniversalAddress +const emitterAddr = ethAddr.toUniversalAddress().toString(); +``` -## Usage +### Tokens -Getting your integration started is simple. First, import Wormhole: +The `TokenId` type identifies any token by its chain and address. For standardized tokens, Wormhole uses the token's contract address. For native currencies (e.g., ETH on Ethereum), it uses the keyword `native`. This ensures consistent handling of all tokens. ```ts -import { wormhole } from '@wormhole-foundation/sdk'; +// Get the TokenId for an ERC-20 token +const sourceToken: TokenId = Wormhole.tokenId('Ethereum', '0xbeef...'); +// Get the TokenId for native ETH +const gasToken: TokenId = Wormhole.tokenId('Ethereum', 'native'); +// Convert a TokenId back to a string +const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' +``` -import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; -import algorand from '@wormhole-foundation/sdk/algorand'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { getSigner } from './helpers/index.js'; +### Signers -(async function () { - const wh = await wormhole('Testnet', [ - evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); +The SDK's `Signer` interface can be implemented as either a `SignOnlySigner` or a `SignAndSendSigner`, created by wrapping an offline or web wallet: - const ctx = wh.getChain('Solana'); +- **`SignOnlySigner`**: Signs and serializes unsigned transactions without broadcasting them. Transactions can be inspected or modified before signing. Serialization is chain-specific. See testing signers (e.g., [EVM](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/evm/src/signer.ts){target=\_blank}, [Solana](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/solana/src/signer.ts){target=\_blank}) for implementation examples. +- **`SignAndSendSigner`**: Signs and broadcasts transactions, returning their transaction IDs in order. - const rcv = wh.getChain('Algorand'); +```ts +export type Signer = SignOnlySigner | SignAndSendSigner; - const sender = await getSigner(ctx); - const receiver = await getSigner(rcv); - - // Get a Token Bridge contract client on the source - const sndTb = await ctx.getTokenBridge(); - - // Send the native token of the source chain - const tokenId = Wormhole.tokenId(ctx.chain, 'native'); - - // Bigint amount using `amount` module - const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); - - // Create a transaction stream for transfers - const transfer = sndTb.transfer( - sender.address.address, - receiver.address, - tokenId.address, - amt - ); - - // Sign and send the transaction - const txids = await signSendWait(ctx, transfer, sender.signer); - console.log('Sent: ', txids); - - // Get the Wormhole message ID from the transaction - const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); - console.log('Wormhole Messages: ', whm); - - const vaa = await wh.getVaa( - // Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 - ); - - // Now get the token bridge on the redeem side - const rcvTb = await rcv.getTokenBridge(); - - // Create a transaction stream for redeeming - const redeem = rcvTb.redeem(receiver.address.address, vaa!); - - // Sign and send the transaction - const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); - console.log('Sent: ', rcvTxids); - - // Now check if the transfer is completed according to - // the destination token bridge - const finished = await rcvTb.isTransferCompleted(vaa!); - console.log('Transfer completed: ', finished); -})(); -``` - -Then, import each of the ecosystem [platforms](#platforms) that you wish to support: - -```ts -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -``` - - -To make the [platform](#platforms) modules available for use, pass them to the Wormhole constructor: - -```ts -evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); -``` - -With a configured Wormhole object, you can do things like parse addresses for the provided platforms, get a [`ChainContext`](#chain-context) object, or fetch VAAs. - -```ts - -``` - -You can retrieve a VAA as follows. In this example, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will vary by network. - -```ts -// Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 - ); -``` - -??? code "View the complete script" - ```ts - import { wormhole } from '@wormhole-foundation/sdk'; - -import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; -import algorand from '@wormhole-foundation/sdk/algorand'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { getSigner } from './helpers/index.js'; - -(async function () { - const wh = await wormhole('Testnet', [ - evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); - - const ctx = wh.getChain('Solana'); - - const rcv = wh.getChain('Algorand'); - - const sender = await getSigner(ctx); - const receiver = await getSigner(rcv); - - // Get a Token Bridge contract client on the source - const sndTb = await ctx.getTokenBridge(); - - // Send the native token of the source chain - const tokenId = Wormhole.tokenId(ctx.chain, 'native'); - - // Bigint amount using `amount` module - const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); - - // Create a transaction stream for transfers - const transfer = sndTb.transfer( - sender.address.address, - receiver.address, - tokenId.address, - amt - ); - - // Sign and send the transaction - const txids = await signSendWait(ctx, transfer, sender.signer); - console.log('Sent: ', txids); - - // Get the Wormhole message ID from the transaction - const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); - console.log('Wormhole Messages: ', whm); - - const vaa = await wh.getVaa( - // Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 - ); - - // Now get the token bridge on the redeem side - const rcvTb = await rcv.getTokenBridge(); - - // Create a transaction stream for redeeming - const redeem = rcvTb.redeem(receiver.address.address, vaa!); - - // Sign and send the transaction - const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); - console.log('Sent: ', rcvTxids); - - // Now check if the transfer is completed according to - // the destination token bridge - const finished = await rcvTb.isTransferCompleted(vaa!); - console.log('Transfer completed: ', finished); -})(); - ``` - -Optionally, you can override the default configuration with a partial `WormholeConfig` object to specify particular fields, such as a different RPC endpoint. - -```ts -const wh = await wormhole('Testnet', [solana], { - chains: { - Solana: { - contracts: { - coreBridge: '11111111111111111111111111111', - }, - rpc: 'https://api.devnet.solana.com', - }, - }, -}); -``` - -??? code "View the complete script" - ```ts - import { wormhole } from '@wormhole-foundation/sdk'; -import solana from '@wormhole-foundation/sdk/solana'; -(async function () { - const wh = await wormhole('Testnet', [solana], { - chains: { - Solana: { - contracts: { - coreBridge: '11111111111111111111111111111', - }, - rpc: 'https://api.devnet.solana.com', - }, - }, - }); - console.log(wh.config.chains.Solana); -})(); - ``` - -## Concepts - -Understanding several higher-level Wormhole concepts and how the SDK abstracts them away will help you use the tools most effectively. The following sections will introduce and discuss the concepts of platforms, chain contexts, addresses, signers, and protocols, how they are used in the Wormhole context, and how the SDK helps ease development in each conceptual area. - -### Platforms - -While every chain has unique attributes, chains from the same platform typically have standard functionalities they share. The SDK includes `Platform` modules, which create a standardized interface for interacting with the chains of a supported platform. The contents of a module vary by platform but can include: - -- Protocols, such as [Wormhole core](#wormhole-core), preconfigured to suit the selected platform -- Definitions and configurations for types, signers, addresses, and chains -- Helpers configured for dealing with unsigned transactions on the selected platform - -These modules also import and expose essential functions and define types or constants from the chain's native ecosystem to reduce the dependencies needed to interact with a chain using Wormhole. Rather than installing the entire native package for each desired platform, you can install a targeted package of standardized functions and definitions essential to connecting with Wormhole, keeping project dependencies as slim as possible. - - -Wormhole currently supports the following platforms: - -- EVM -- Solana -- Cosmos -- Sui -- Aptos -- Algorand - -See the [Platforms folder of the TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms){target=\_blank} for an up-to-date list of the platforms supported by the Wormhole TypeScript SDK. - -### Chain Context - -The `definitions` package of the SDK includes the `ChainContext` class, which creates an interface for working with connected chains in a standardized way. This class contains the network, chain, and platform configurations for connected chains and cached RPC and protocol clients. The `ChainContext` class also exposes chain-specific methods and utilities. Much of the functionality comes from the `Platform` methods but some specific chains may have overridden methods via the context. This is also where the `Network`, `Chain`, and `Platform` type parameters which are used throughout the package are defined. - -```ts -const srcChain = wh.getChain(senderAddress.chain); -const dstChain = wh.getChain(receiverAddress.chain); - -const tb = await srcChain.getTokenBridge(); // => TokenBridge<'Evm'> -srcChain.getRpcClient(); // => RpcClient<'Evm'> -``` - -### Addresses - -The SDK uses the `UniversalAddress` class to implement the `Address` interface, which all address types must implement. Addresses from various networks are parsed into their byte representation and modified as needed to ensure they are exactly 32 bytes long. Each platform also has an address type that understands the native address formats, referred to as `NativeAddress.` These abstractions allow you to work with addresses consistently regardless of the underlying chain. - -```ts -// It's possible to convert a string address to its Native address -const ethAddr: NativeAddress<'Evm'> = toNative('Ethereum', '0xbeef...'); - -// A common type in the SDK is the `ChainAddress` which provides -// the additional context of the `Chain` this address is relevant for -const senderAddress: ChainAddress = Wormhole.chainAddress( - 'Ethereum', - '0xbeef...' -); -const receiverAddress: ChainAddress = Wormhole.chainAddress( - 'Solana', - 'Sol1111...' -); - -// Convert the ChainAddress back to its canonical string address format -const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' - -// Or if the ethAddr above is for an emitter and you need the UniversalAddress -const emitterAddr = ethAddr.toUniversalAddress().toString(); -``` - -### Tokens - -Similar to the `ChainAddress` type, the `TokenId` type provides the chain and address of a given token. The following snippet introduces `TokenId`, a way to uniquely identify any token, whether it's a standard token or a blockchain's native currency (like ETH for Ethereum). - -Wormhole uses their contract address to create a `TokenId` for standard tokens. For native currencies, Wormhole uses the keyword `native` instead of an address. This makes it easy to work with any type of token consistently. - -Finally, the snippet demonstrates how to convert a `TokenId` back into a regular address format when needed. - -```ts -const sourceToken: TokenId = Wormhole.tokenId('Ethereum', '0xbeef...'); - -const gasToken: TokenId = Wormhole.tokenId('Ethereum', 'native'); - -const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' -``` - -### Signers - -Certain methods of signing transactions require a `Signer` interface in the SDK. Depending on the specific requirements, this interface can be fulfilled by either a `SignOnlySigner` or a `SignAndSendSigner`. A signer can be created by wrapping an offline or web wallet. - -A `SignOnlySigner` is used when the signer isn't connected to the network or prefers not to broadcast transactions themselves. It accepts an array of unsigned transactions and returns an array of signed and serialized transactions. Before signing, the transactions may be inspected or altered. It's important to note that the serialization process is chain-specific. Refer to the testing signers (e.g., [EVM](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/evm/src/signer.ts){target=\_blank} or [Solana](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/solana/src/signer.ts){target=\_blank}) for an example of how to implement a signer for a specific chain or platform. - -Conversely, a `SignAndSendSigner` is appropriate when the signer is connected to the network and intends to broadcast the transactions. This type of signer also accepts an array of unsigned transactions but returns an array of transaction IDs corresponding to the order of the unsigned transactions. - -```ts -export type Signer = SignOnlySigner | SignAndSendSigner; - -export interface SignOnlySigner { - chain(): ChainName; - address(): string; - // Accept an array of unsigned transactions and return - // an array of signed and serialized transactions. - // The transactions may be inspected or altered before - // signing. - sign(tx: UnsignedTransaction[]): Promise; -} +export interface SignOnlySigner { + chain(): ChainName; + address(): string; + // Accept an array of unsigned transactions and return + // an array of signed and serialized transactions. + // The transactions may be inspected or altered before + // signing. + sign(tx: UnsignedTransaction[]): Promise; +} export interface SignAndSendSigner { chain(): ChainName; @@ -2551,7 +2880,7 @@ export interface SignAndSendSigner { #### Set Up a Signer with Ethers.js -To sign transactions programmatically with the Wormhole SDK, you can use Ethers.js to manage private keys and handle signing. Here's an example of setting up a signer using Ethers.js: +To sign transactions programmatically with the Wormhole SDK, you can use [Ethers.js](https://docs.ethers.org/){target=\_blank} to manage private keys and handle signing. Here's an example of setting up a signer using Ethers.js: ```javascript import { ethers } from 'ethers'; @@ -2580,47 +2909,63 @@ async function sendTransaction() { sendTransaction(); ``` - - **`provider`** - responsible for connecting to the Ethereum network (or any EVM-compatible network). It acts as a bridge between your application and the blockchain, allowing you to fetch data, check the state of the blockchain, and submit transactions - - - **`signer`** - represents the account that will sign the transaction. In this case, you’re creating a signer using the private key associated with the account. The signer is responsible for authorizing transactions by digitally signing them with the private key - - - **`Wallet`** - combines both the provider (for blockchain interaction) and the signer (for transaction authorization), allowing you to sign and send transactions programmatically +These components work together to create, sign, and submit a transaction to the blockchain: -These components work together to create, sign, and submit a transaction to the blockchain. - -???- tip "Managing Private Keys Securely" - Handling private keys is unavoidable, so it’s crucial to manage them securely. Here are some best practices: - - - **Use environment variables** - avoid hardcoding private keys in your code. Use environment variables or secret management tools to inject private keys securely - - **Hardware wallets** - for production environments, consider integrating hardware wallets to keep private keys secure while allowing programmatic access through the SDK +- **`provider`**: Connects to the Ethereum or EVM-compatible network, enabling data access and transaction submission. +- **`signer`** : Represents the account that signs transactions using a private key. +- **`Wallet`**: Combines provider and signer to create, sign, and send transactions programmatically. ### Protocols -While Wormhole is a Generic Message Passing (GMP) protocol, several protocols have been built to provide specific functionality. If available, each protocol will have a platform-specific implementation. These implementations provide methods to generate transactions or read state from the contract on-chain. - -#### Wormhole Core - -The core protocol underlies all Wormhole activity. This protocol is responsible for emitting the message containing the information necessary to perform bridging, including the [emitter address](https://docs.wormhole.com/wormhole/reference/glossary#emitter){target=\_blank}, the [sequence number](https://docs.wormhole.com/wormhole/reference/glossary#sequence){target=\_blank} for the message, and the payload of the message itself. +Wormhole is a Generic Message Passing (GMP) protocol with several specialized protocols built on top. Each protocol has platform-specific implementations providing methods to generate transactions or read on-chain state. + +??? interface "Supported protocol modules" + + | Protocol | Installation Command | + |-----------------------|----------------------------------------------------------------| + | EVM Core |
```@wormhole-foundation/sdk-evm-core```
| + | EVM Token Bridge |
```@wormhole-foundation/sdk-evm-tokenbridge```
| + | EVM CCTP |
```@wormhole-foundation/sdk-evm-cctp```
| + | EVM Portico |
```@wormhole-foundation/sdk-evm-portico```
| + | EVM TBTC |
```@wormhole-foundation/sdk-evm-tbtc```
| + | Solana Core |
```@wormhole-foundation/sdk-solana-core```
| + | Solana Token Bridge |
```@wormhole-foundation/sdk-solana-tokenbridge```
| + | Solana CCTP |
```@wormhole-foundation/sdk-solana-cctp```
| + | Solana TBTC |
```@wormhole-foundation/sdk-solana-tbtc```
| + | Algorand Core |
```@wormhole-foundation/sdk-algorand-core```
| + | Algorand Token Bridge |
```@wormhole-foundation/sdk-algorand-tokenbridge```
| + | Aptos Core |
```@wormhole-foundation/sdk-aptos-core```
| + | Aptos Token Bridge |
```@wormhole-foundation/sdk-aptos-tokenbridge```
| + | Aptos CCTP |
```@wormhole-foundation/sdk-aptos-cctp```
| + | Cosmos Core |
```@wormhole-foundation/sdk-cosmwasm-core```
| + | Cosmos Token Bridge |
```@wormhole-foundation/sdk-cosmwasm-tokenbridge```
| + | Sui Core |
```@wormhole-foundation/sdk-sui-core```
| + | Sui Token Bridge |
```@wormhole-foundation/sdk-sui-tokenbridge```
| + | Sui CCTP |
```@wormhole-foundation/sdk-sui-cctp```
| -The following example demonstrates sending and verifying a message using the Wormhole Core protocol on Solana. -First, initialize a Wormhole instance for the Testnet environment, specifically for the Solana chain. Then, obtain a signer and its associated address, which will be used to sign transactions. +#### Wormhole Core -Next, get a reference to the core messaging bridge, which is the main interface for interacting with Wormhole's cross-chain messaging capabilities. -The code then prepares a message for publication. This message includes: +The core protocol powers all Wormhole activity by emitting messages containing the [emitter address](/docs/products/reference/glossary/#emitter){target=\_blank}, sequence number, and payload needed for bridging. -- The sender's address -- The message payload (in this case, the encoded string `lol`) -- A nonce (set to `0` here, but can be any user-defined value to uniquely identify the message) -- A [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} (set to `0`, which determines the finality requirements for the message) +Example workflow on Solana Testnet: -After preparing the message, the next steps are to generate, sign, and send the transaction or transactions required to publish the message on the Solana blockchain. Once the transaction is confirmed, the Wormhole message ID is extracted from the transaction logs. This ID is crucial for tracking the message across chains. +1. Initialize a Wormhole instance for Solana. +2. Obtain a signer and its address. +3. Access the core messaging bridge for cross-chain messaging. +4. Prepare a message with: -The code then waits for the Wormhole network to process and sign the message, turning it into a Verified Action Approval (VAA). This VAA is retrieved in a `Uint8Array` format, with a timeout of 60 seconds. + - Sender's address + - Encoded payload (e.g., "lol") + - Nonce (e.g., 0) + - Consistency level (e.g., 0) -Lastly, the code will demonstrate how to verify the message on the receiving end. A verification transaction is prepared using the original sender's address and the VAA, and finally, this transaction is signed and sent. +5. Generate, sign, and send the transaction to publish the message. +6. Extract the Wormhole message ID from transaction logs for tracking. +7. Wait (up to 60s) to receive the [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} (in `Uint8Array` format) from the Wormhole network. +8. Prepare and send a verification transaction on the receiving chain using the sender's address and the VAA. -???+ code "View the complete script" +???+ example "Example workflow" ```ts import { encoding, signSendWait, wormhole } from '@wormhole-foundation/sdk'; import { getSigner } from './helpers/index.js'; @@ -2675,7 +3020,7 @@ The payload contains the information necessary to perform whatever action is req #### Token Bridge -The most familiar protocol built on Wormhole is the Token Bridge. Every chain has a `TokenBridge` protocol client that provides a consistent interface for interacting with the Token Bridge, which includes methods to generate the transactions required to transfer tokens and methods to generate and redeem attestations. `WormholeTransfer` abstractions are the recommended way to interact with these protocols, but it is possible to use them directly. +The most familiar protocol built on Wormhole is the Token Bridge. Each supported chain has a `TokenBridge` client that provides a consistent interface for transferring tokens and handling attestations. While `WormholeTransfer` abstractions are recommended, direct interaction with the protocol is also supported. ```ts import { signSendWait } from '@wormhole-foundation/sdk'; @@ -2687,8 +3032,6 @@ const txGenerator = tb.createAttestation(token); const txids = await signSendWait(srcChain, txGenerator, src.signer); ``` -Supported protocols are defined in the [definitions module](https://github.com/wormhole-foundation/connect-sdk/tree/main/core/definitions/src/protocols){target=\_blank}. - ## Transfers While using the [`ChainContext`](#chain-context) and [`Protocol`](#protocols) clients directly is possible, the SDK provides some helpful abstractions for transferring tokens. @@ -2697,17 +3040,15 @@ The `WormholeTransfer` interface provides a convenient abstraction to encapsulat ### Token Transfers -Performing a token transfer is trivial for any source and destination chains. You can create a new `Wormhole` object to make objects like `TokenTransfer` and `CircleTransfer`, to transfer tokens between chains. - -The following example demonstrates the process of initiating and completing a token transfer. It starts by creating a `TokenTransfer` object, which tracks the transfer's state throughout its lifecycle. The code then obtains a quote for the transfer, ensuring the amount is sufficient to cover fees and any requested native gas. +Token transfers between chains are straightforward using Wormhole. Create a `Wormhole` instance and use it to initialize a `TokenTransfer` or `CircleTransfer` object. -The transfer process is divided into three main steps: +The example below shows how to initiate and complete a `TokenTransfer`. After creating the transfer object and retrieving a quote (to verify sufficient amount and fees), the process involves: -1. Initiating the transfer on the source chain -2. Waiting for the transfer to be attested (if not automatic) -3. Completing the transfer on the destination chain +1. Initiating the transfer on the source chain. +2. Waiting for attestation (if required). +3. Completing the transfer on the destination chain. -For automatic transfers, the process ends after initiation. The code waits for the transfer to be attested for manual transfers and then completes it on the destination chain. +For automatic transfers, the process ends after initiation. Manual transfers require attestation before completion. ```ts const xfer = await wh.tokenTransfer( @@ -2926,17 +3267,15 @@ async function tokenTransfer( ``` -Internally, this uses the [TokenBridge](#token-bridge) protocol client to transfer tokens. Like other Protocols, the `TokenBridge` protocol provides a consistent set of methods across all chains to generate a set of transactions for that specific chain. +Internally, this uses the [`TokenBridge`](#token-bridge) protocol client to transfer tokens. ### Native USDC Transfers -You can also transfer native USDC using [Circle's CCTP](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. Please note that if the transfer is set to `Automatic` mode, a fee for performing the relay will be included in the quote. This fee is deducted from the total amount requested to be sent. For example, if the user wishes to receive `1.0` on the destination, the amount sent should be adjusted to `1.0` plus the relay fee. The same principle applies to native gas drop offs. +You can transfer native USDC using [Circle's CCTP](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. If the transfer is set to `automatic`, the quote will include a relay fee, which is deducted from the total amount sent. For example, to receive 1.0 USDC on the destination chain, the sender must cover both the 1.0 and the relay fee. The same applies when including a native gas drop-off. -In the following example, the `wh.circleTransfer` function is called with several parameters to set up the transfer. It takes the amount to be transferred (in the token's base units), the sender's chain and address, and the receiver's chain and address. The function also allows specifying whether the transfer should be automatic, meaning it will be completed without further user intervention. +In the example below, the `wh.circleTransfer` function is used to initiate the transfer. It accepts the amount (in base units), sender and receiver chains and addresses, and an optional automatic flag to enable hands-free completion. You can also include an optional payload (set to `undefined` here) and specify a native gas drop-off if desired. -An optional payload can be included with the transfer, though it's set to undefined in this case. Finally, if the transfer is automatic, you can request that native gas (the blockchain's native currency used for transaction fees) be sent to the receiver along with the transferred tokens. - -When waiting for the `VAA`, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will [vary by network](https://developers.circle.com/stablecoins/docs/required-block-confirmations#mainnet){target=\_blank}. +When waiting for the VAA, a timeout of `60,000` milliseconds is used. The actual wait time [varies by network](https://developers.circle.com/stablecoins/docs/required-block-confirmations#mainnet){target=\_blank}. ```ts // Amount as bigint (base units) @@ -3320,11 +3659,9 @@ Once the tokens are selected, a `RouteTransferRequest` may be created to provide ); ``` -Choosing the best route is currently left to the developer, but strategies might include sorting by output amount or expected time to complete the transfer (no estimate is currently provided). - -After choosing the best route, extra parameters like `amount`, `nativeGasDropoff`, and `slippage` can be passed, depending on the specific route selected. A quote can be retrieved with the validated request. +Choosing the best route is up to the developer and may involve sorting by output amount or estimated completion time (though no estimate is currently provided). -After successful validation, the code requests a transfer quote. This quote likely includes important details such as fees, estimated time, and the final amount to be received. If the quote is generated successfully, it's displayed for the user to review and decide whether to proceed with the transfer. This process ensures that all transfer details are properly set up and verified before any actual transfer occurs. +Once a route is selected, parameters like `amount`, `nativeGasDropoff`, and `slippage` can be set. After validation, a transfer quote is requested, including fees, estimated time, and final amount. If successful, the quote is shown to the user for review before proceeding, ensuring all details are verified prior to transfer. ```ts 'This route offers the following default options', @@ -3522,2090 +3859,2485 @@ This context is provided to help understand how the system works under the hood, ## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/learn/glossary/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Glossary +# Get Started with Messaging -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. -## Chain ID +## Prerequisites -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +Before you begin, ensure you have the following: -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions -## Consistency Level +## Configure Your Messaging Environment -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a directory and initialize a Node.js project: -## Delivery Provider + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Emitter + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -## Finality + ```bash + npx tsc --init + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. + Make sure your `tsconfig.json` includes the following settings: -## Guardian + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -## Guardian Network + ```bash + npm install @wormhole-foundation/sdk + ``` -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +5. Create a new file named `main.ts`: -## Guardian Set + ```bash + touch main.ts + ``` -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. +## Construct and Publish Your Message -## Heartbeat +1. Open `main.ts` and update the code there as follows: -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; + +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ + +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; + +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); + + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; + + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -## Observation + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); -## Relayer + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; -A relayer is any process that delivers VAAs to a destination. + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); -## Sequence + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); -## Spy + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; -## VAA + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -## Validator + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); + } + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); + } + } +} -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. ---- END CONTENT --- +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ ---- BEGIN CONTENT --- ---- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics ---- + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -# Infrastructure Components +2. Run the script using the following command: -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. + ```bash + npx tsx main.ts + ``` -## Get Started + You will see terminal output similar to the following: + +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-Start here for an overview of Wormhole architecture components and security mechanisms: +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -
+Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** +## Next Steps - --- +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +categories: Basics +--- - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +# Get Started with Core Contracts -- :octicons-book-16:{ .lg .middle } **Security** +## Introduction - --- +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. - [:custom-arrow: Learn About Security](/docs/learn/security/) +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. -
+## Prerequisites -## Explore Components +To interact with the Wormhole Core Contract, you'll need the following: -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +## How to Interact with Core Contracts -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -## Next Steps +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -
+While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -- :octicons-book-16:{ .lg .middle } **Messaging Components** +### Sending Messages - --- +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers +=== "EVM" - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` - --- + ??? interface "Parameters" - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + --- -
---- END CONTENT --- + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + --- -# Architecture + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. -## Overview + ??? interface "Returns" -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. +// Check fee and send parameters - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -## On-Chain Components +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -## Off-Chain Components +=== "Solana" -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -## Next Steps + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -
+ ??? interface "Parameters" -- :octicons-book-16:{ .lg .middle } **Core Contracts** + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - --- + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -- :octicons-tools-16:{ .lg .middle } **Core Messaging** + ??? child "Type `PostMessage<'info>`" + + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` - --- + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. + --- - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + `batch_id` ++"u32"++ + + An identifier for the message batch. -
---- END CONTENT --- + --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics ---- + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -# Core Contracts + --- -## Introduction + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" -## Key Functions + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -Key functions of the Wormhole Core Contract include the following: +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -## How the Core Contract Works + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The following describes the role of the Wormhole Core Contract in message transfers: +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions +### Receiving Messages -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. +The way a message is received and handled depends on the environment. -### Message Submission +=== "EVM" -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. + ??? interface "Parameters" -### Message Reception + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + ??? interface "Returns" -## Multicast + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. + ??? child "Struct `VM`" -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- -## Next Steps + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -
+ ??? interface "Example" -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); - --- + // Perform safety checks here - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + // Your custom application logic here +} + ``` -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - --- +=== "Solana" - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + Retrieve the raw message data: -
---- END CONTENT --- + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- + ??? interface "Example" -## Guardian + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -Guardians fulfill their role in the messaging protocol as follows: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +#### Validating the Emitter -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -## Guardian Network +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` -The Guardian Network is designed to help Wormhole deliver on five key principles: +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +```typescript +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); -The following sections explore each principle in detail. +await tx.wait(); +``` -### Decentralization +#### Additional Checks -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -Two common approaches to decentralization have notable limitations: +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. +## Source Code References -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -To answer that, consider these key constraints and design decisions: +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +# Wormhole Relayer -### Modularity +## Introduction -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -### Chain Agnosticism +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +## Get Started with the Wormhole Relayer -### Scalability +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +### Wormhole Relayer Interfaces -### Upgradeable +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -Wormhole is designed to adapt and evolve in the following ways: +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +## Interact with the Wormhole Relayer -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -## Next Steps +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -
+To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -- :octicons-book-16:{ .lg .middle } **Relayers** +Your initial set up should resemble the following: - --- +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +contract Example { + IWormholeRelayer public wormholeRelayer; -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} +``` - --- +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +### Send a Message - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -
---- END CONTENT --- +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); +``` -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -# Relayers +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); +``` -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -There are three primary types of relayers discussed: +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); +``` -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient +### Receive a Message -## Fundamentals +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Key characteristics of VAAs include: +## Delivery Guarantees -- Public emission from the Guardian Network +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -- Authentication through signatures from the Guardian Network +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -- Verifiability by any entity or any Wormhole Core Contract +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. +## Delivery Statuses -Keep in mind the following security considerations around relayers: +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -## Client-Side Relaying +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -### Key Features +## Other Considerations -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -### Implementation +## Track the Progress of Messages with the Wormhole CLI -Users themselves carry out the three steps of the cross-chain process: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -1. Perform an action on chain A +=== "Mainnet" -2. Retrieve the resulting VAA from the Guardian Network + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` -3. Perform an action on chain B using the VAA +=== "Testnet" -### Considerations + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -- Users must sign all required transactions with their own wallet +## Step-by-Step Tutorial -- Users must have funds to pay the transaction fees on every chain involved +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -- The user experience may be cumbersome due to the manual steps involved +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -## Custom Relayers +# Messaging Overview -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +## Key Features -### Key Features +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## How It Works -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +The messaging flow consists of several core components: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -### Implementation +## Use Cases -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. -### Considerations +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -- Development work and hosting of relayers are required +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +- **Gas Abstraction** -## Wormhole Relayers + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. +- **Bridging Intent Library** -### Key Features + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. -- **Lower operational costs** - no need to develop, host, or maintain individual relayers +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. -### Implementation +## Next Steps -The Wormhole relayer integration involves two key steps: +Follow these steps to work with Wormhole Messaging: -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- -### Considerations +# Products -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. -- All computations are performed on-chain +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -- Potentially less gas-efficient compared to custom relayers +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +## Transfer Products -- Support may not be available for all chains +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -## Next Steps +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -
+
-- :octicons-book-16:{ .lg .middle } **Spy** +::spantable:: - --- +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +::end-spantable:: - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) +
-- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: - --- +
- Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) +## Bridging UI -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. - --- +## Real-time Data - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) +## Multichain Governance -
+[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. categories: Basics --- -# Spy - -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. - -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - -## Key Features - -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - -## Integrator Use Case - -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - -## Observable Message Categories +# Glossary -A Spy can access the following categories of messages shared over the gossip protocol: +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +## Chain ID - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +## Consistency Level -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network +## Delivery Provider -## Additional Resources +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. -
+## Emitter -- :octicons-code-16:{ .lg .middle } **Spy Source Code** +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - --- +## Finality - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} +## Guardian -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - --- +## Guardian Network - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +## Guardian Set -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. - --- +## Heartbeat - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -
+## Observation -## Next Steps +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. -
+## Relayer -- :octicons-code-16:{ .lg .middle } **Run a Spy** +A relayer is any process that delivers VAAs to a destination. - --- +## Sequence - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +## Spy -- :octicons-code-16:{ .lg .middle } **Use Queries** +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - --- +## VAA - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +## Validator -
+A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/protocol/architecture/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. categories: Basics --- -# Verified Action Approvals - -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. - -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. - -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +# Architecture -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +## Overview -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -## VAA Format +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -The basic VAA consists of header and body components described as follows: +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. - Where each `signature` is: + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on +## On-Chain Components -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. +## Off-Chain Components -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -## Consistency and Finality +## Next Steps -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +
-Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- :octicons-book-16:{ .lg .middle } **Core Contracts** -## Signatures + --- -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- :octicons-tools-16:{ .lg .middle } **Core Messaging** -## Payload Types + --- -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. -### Token Transfer + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +
+--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# The Wormhole Ecosystem -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +## Ecosystem Overview -### Attestation +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -The message format for token attestation is as follows: +## Bringing It All Together: Interoperability in Action -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. -#### Attestation Tips +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. -Be aware of the following considerations when working with attestations: +## Next Steps -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. +--- END CONTENT --- -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +# Core Contracts -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Introduction -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer with Message +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +## Key Functions -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +Key functions of the Wormhole Core Contract include the following: -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +## How the Core Contract Works -### Governance +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +The following describes the role of the Wormhole Core Contract in message transfers: -#### Action Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +### Message Submission -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -#### Actions +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +### Message Reception -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -## Lifetime of a Message +## Multicast -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. ## Next Steps
-- :octicons-book-16:{ .lg .middle } **Guardians** +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** --- - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** --- - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/introduction/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. categories: Basics --- -# Introduction to Wormhole - -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. - -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. - -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. - -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) - -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. - -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. - -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. - -## What Problems Does Wormhole Solve? - -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. - -Critical problems Wormhole addresses include: +## Guardian -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -## What Does Wormhole Offer? +Guardians fulfill their role in the messaging protocol as follows: -Wormhole provides a suite of tools and protocols that support a wide range of use cases: +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -## What Isn't Wormhole? +## Guardian Network -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -## Use Cases of Wormhole +The Guardian Network is designed to help Wormhole deliver on five key principles: -Consider the following examples of potential applications enabled by Wormhole: +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +The following sections explore each principle in detail. -## Explore +### Decentralization -Discover more about the Wormhole ecosystem, components, and protocols: +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +Two common approaches to decentralization have notable limitations: -## Demos +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment -Demos offer more realistic implementations than tutorials: +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? - +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -!!! note - Wormhole Integration Complete? +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +### Modularity - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. -## Supported Blockchains +### Chain Agnosticism -Wormhole supports a growing number of blockchains. +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. -text/supported-networks.md ---- END CONTENT --- +### Scalability -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -# Security +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. -## Core Security Assumptions +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +### Upgradeable -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +Wormhole is designed to adapt and evolve in the following ways: -In summary: +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. +## Next Steps -## Guardian Network +
-Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +- :octicons-book-16:{ .lg .middle } **Relayers** -### Governance + --- -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. + --- -Via governance, the Guardians can: + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +
+--- END CONTENT --- -## Monitoring +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ +--- BEGIN CONTENT --- +--- +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +categories: Basics +--- -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. +# Relayers -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Guardians monitor: +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators +There are three primary types of relayers discussed: -## Asset Layer Protections +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. +## Fundamentals -## Open Source +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Wormhole builds in the open and is always open source. +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** +Key characteristics of VAAs include: -## Audits +- Public emission from the Guardian Network -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: +- Authentication through signatures from the Guardian Network -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} +- Verifiability by any entity or any Wormhole Core Contract -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -## Bug Bounties +Keep in mind the following security considerations around relayers: -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. +## Client-Side Relaying -## Learn More +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +### Key Features -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ ---- BEGIN CONTENT --- ---- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics ---- +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -# Get Started with Core Contracts +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -## Introduction +### Implementation -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +Users themselves carry out the three steps of the cross-chain process: -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +1. Perform an action on chain A -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +2. Retrieve the resulting VAA from the Guardian Network -## Prerequisites +3. Perform an action on chain B using the VAA -To interact with the Wormhole Core Contract, you'll need the following: +### Considerations -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. -## How to Interact with Core Contracts +- Users must sign all required transactions with their own wallet -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +- Users must have funds to pay the transaction fees on every chain involved -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +- The user experience may be cumbersome due to the manual steps involved -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +## Custom Relayers -### Sending Messages +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). -=== "EVM" +### Key Features - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); - ``` +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more - ??? interface "Parameters" +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - --- +### Implementation - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. - --- +### Considerations - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - ??? interface "Returns" +- Development work and hosting of relayers are required - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); +- Relayers are responsible for availability, and adding dependencies for the cross-chain application -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +## Wormhole Relayers -// Check fee and send parameters +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); +### Key Features -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +### Implementation -=== "Solana" +The Wormhole relayer integration involves two key steps: - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` +- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA - ??? interface "Parameters" +### Considerations - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" +- All computations are performed on-chain - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` +- Potentially less gas-efficient compared to custom relayers - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted - ??? child "Type `PostMessage<'info>`" +- Support may not be available for all chains - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` +## Next Steps - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. +
- --- +- :octicons-book-16:{ .lg .middle } **Spy** - `batch_id` ++"u32"++ - - An identifier for the message batch. + --- - --- + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - --- +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" + --- - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; + --- -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +
+--- END CONTENT --- -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- -### Receiving Messages +# Spy -The way a message is received and handled depends on the environment. +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -=== "EVM" +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +## Key Features - ??? interface "Parameters" +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. +## Integrator Use Case - ??? interface "Returns" +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. - ??? child "Struct `VM`" +## Observable Message Categories - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` +A Spy can access the following categories of messages shared over the gossip protocol: - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network - ??? interface "Example" + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status - // Perform safety checks here + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); +## Additional Resources - // Your custom application logic here -} - ``` +
- View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -=== "Solana" + --- - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. - Retrieve the raw message data: + [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** - ??? interface "Example" + --- - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) - } -} - - ``` + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** -#### Validating the Emitter + --- -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` +
-This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. +## Next Steps -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); +
-await tx.wait(); -``` +- :octicons-code-16:{ .lg .middle } **Run a Spy** -#### Additional Checks + --- -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. +- :octicons-code-16:{ .lg .middle } **Use Queries** -## Source Code References + --- -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) + +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ --- BEGIN CONTENT --- --- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics --- -# Wormhole Relayer - -## Introduction - -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. - -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. +# Verified Action Approvals -## Get Started with the Wormhole Relayer +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -### Wormhole Relayer Interfaces +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: +## VAA Format -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from +The basic VAA consists of header and body components described as follows: -## Interact with the Wormhole Relayer +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. + Where each `signature` is: -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on -Your initial set up should resemble the following: +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. -contract Example { - IWormholeRelayer public wormholeRelayer; +## Consistency and Finality - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. -### Send a Message +## Signatures -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) ``` -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. +## Payload Types -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. +### Token Transfer -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); +Transferring tokens from the sending chain to the destination chain requires the following steps: -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -### Receive a Message +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. -The logic inside the function body may be whatever business logic is required to take action on the specific payload. +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. -## Delivery Guarantees +### Attestation -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. +The message format for token attestation is as follows: -## Delivery Statuses +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: +#### Attestation Tips -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure +Be aware of the following considerations when working with attestations: -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -## Other Considerations +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: +### Token Transfer with Message -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -## Track the Progress of Messages with the Wormhole CLI +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: -=== "Mainnet" +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` +### Governance -=== "Testnet" +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` +#### Action Structure -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -## Step-by-Step Tutorial +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -# Products +#### Actions -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +## Lifetime of a Message -## Transfer Products +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -
+![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) -::spantable:: +## Next Steps -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +
-::end-spantable:: +- :octicons-book-16:{ .lg .middle } **Guardians** -
+ --- -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -## Bridging UI + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** -## Real-time Data + --- -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. -## Multichain Governance + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ +Doc-Content: https://wormhole.com/docs/protocol/introduction/ --- BEGIN CONTENT --- --- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. categories: Basics --- -# Wormhole Use Cases - -
-
- -## Cross-Chain Swaps and Liquidity Aggregation - -Enable seamless swaps between chains with real-time liquidity routing. - -
-
- -🛠 **Wormhole products used:** - -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution - -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} +# Introduction to Wormhole -
-
+In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -
-
+Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -## Borrowing and Lending Across Chains +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) -Let users borrow assets on one chain using collateral from another. +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. -
-
+Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. -🛠 **Wormhole products used:** +This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +## What Problems Does Wormhole Solve? -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -
-
+Critical problems Wormhole addresses include: +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -
-
+## What Does Wormhole Offer? -## Real-Time Price Feeds and Trading Strategies +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -Fetch price feeds across multiple chains for DeFi applications. +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -
-
+## What Isn't Wormhole? -🛠 **Wormhole products used:** +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +## Use Cases of Wormhole -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Consider the following examples of potential applications enabled by Wormhole: -
-
+- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. +## Explore -
-
+Discover more about the Wormhole ecosystem, components, and protocols: -## Asset Movement Between Bitcoin and Other Chains +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -Enable direct BTC transfers without wrapped assets. +## Demos -
-
+Demos offer more realistic implementations than tutorials: -🛠 **Wormhole products used:** +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains + -
-
+!!! note + Wormhole Integration Complete? -
-
+ Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -## Decentralized Social Platforms + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -Enable seamless communication and asset transfer across decentralized social networks. +## Supported Networks by Product -
-
+Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. +--- END CONTENT --- -🛠 **Wormhole products used:** +Doc-Content: https://wormhole.com/docs/protocol/security/ +--- BEGIN CONTENT --- +--- +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics +--- -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +# Security -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} +## Core Security Assumptions -
-
+At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -
-
+In summary: -## Memecoin Launchpads +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -
-
+## Guardian Network -🛠 **Wormhole products used:** +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes +### Governance -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -
-
+This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -
-
+All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -## Cross-Chain Perpetuals +Via governance, the Guardians can: -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -
-
+The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -🛠 **Wormhole products used:** +## Monitoring -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -
-
+Guardians monitor: +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators -
-
+## Asset Layer Protections -## Gas Abstraction +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. -
-
+In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. -🛠 **Wormhole products used:** +## Open Source -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +Wormhole builds in the open and is always open source. -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** -
-
+## Audits +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -
-
+- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} -## Bridging Intent Library +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. +## Bug Bounties -
-
+Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. -🛠 **Wormhole products used:** +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -
-
+## Learn More +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- -## Multichain Prediction Markets +# Get Started with the Solidity SDK -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. -
-
+## Install the SDK -🛠 **Wormhole products used:** +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +## Key Components -
-
+The following key components and features work together to make your on-chain Wormhole integration easier to build. +??? interface "Base contracts" -
-
+ Leverage base contracts to send and receive messages and tokens. -## Cross-Chain Payment Widgets + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +??? interface "Interfaces" -
-
+ Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. -🛠 **Wormhole products used:** + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers +??? interface "Constants" -🔗 **Used in:** E-commerce, Web3 payments, and subscription models + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. -
-
+ - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. +## Example Usage -
-
+The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. -## Oracle Networks +### Prerequisites +Before you begin, ensure you have the following: -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -
-
+### Set Up a Project -🛠 **Wormhole products used:** +Follow these steps to prepare your development environment: -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} + ```bash + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -
-
+2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript + ``` -
-
+### Create and Deploy Contracts + +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. + +Follow these steps to create and deploy your sender and receiver Solidity contracts: + +1. Use the following example code to create `CrossChainSender.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + + cost = deliveryCost + wormhole.messageFee(); + } -## Cross-Chain Staking + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -Enable users to stake assets on one chain while earning rewards or securing networks on another. + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. + +2. Use the following example code to create `CrossChainReceiver.sol`: + + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; + +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -
-
+ // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -🛠 **Wormhole products used:** + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } +} + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. -
-
---- END CONTENT --- +## Use Contracts to Transfer USDC -## Reference Concepts [shared: true] +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: -The following section contains reference material for Wormhole. -It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. -While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. + ```bash + touch script/transfer.ts + ``` ---- +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. -## List of shared concept pages: + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. +3. Open `transfer.ts` and add the following code: -## Full content for shared concepts: + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); -# Reference +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } -## Get Started + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -
+ // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet + ); - --- + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } - --- + process.exit(0); +})(); + ``` - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +3. Run the script using the following command: -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```bash + npx tsx script/transfer.ts + ``` - --- +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: + +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - This includes the following protocol contracts: +## Next Steps - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +## Reference Concepts [shared: true] -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** +The following section contains reference material for Wormhole. +It includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. +While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. - --- +--- - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +## List of shared concept pages: - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) -
---- END CONTENT --- +## Full content for shared concepts: -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ --- BEGIN CONTENT --- --- title: Chain IDs @@ -5728,7 +6460,7 @@ The following table documents the chain IDs used by Wormhole and places them alo --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ --- BEGIN CONTENT --- --- title: Wormhole Finality | Consistency Levels @@ -5783,7 +6515,7 @@ The following table documents each chain's `consistencyLevel` values (i.e., fina --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ --- BEGIN CONTENT --- --- title: Contract Addresses @@ -5999,262 +6731,96 @@ categories: Reference | Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | | Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" - - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | - -=== "Testnet" - - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | - -=== "Devnet" - - N/A - - - -## Settlement Token Router - -=== "Mainnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - -=== "Testnet" - - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - - -## Read-Only Deployments - -=== "Mainnet" - - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | - -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- - -# Wormhole Formatted Addresses - -## Introduction - -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. - -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. - -## Platform-Specific Address Formats - -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. - -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: - -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | - -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. - -### Address Format Handling - -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: - -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` - -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. - -## Universal Address Methods - -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. - -Key functions: - - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format - - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` - - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address - - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` - - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform - - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` - - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - - ```typescript - console.log(universalAddress.toString()); - ``` - -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - -## Convert Between Native and Wormhole Formatted Addresses - -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - -### Convert a Native Address to a Wormhole Formatted Address - -Example conversions for EVM and Solana: +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -=== "EVM" +=== "Testnet" - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +=== "Devnet" -=== "Solana" + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +## CCTP -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` + + -The result is a standardized address format that is ready for cross-chain operations. +=== "Mainnet" -### Convert Back to Native Addresses + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +=== "Testnet" -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +=== "Devnet" -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + N/A + + -## Use Cases for Wormhole Formatted Addresses +## Settlement Token Router -### Cross-chain Token Transfers +=== "Mainnet" -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
-### Smart Contract Interactions +=== "Testnet" -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ -### DApp Development +## Read-Only Deployments -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +=== "Mainnet" -### Relayers and Infrastructure + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- title: Supported Networks @@ -6266,7 +6832,7 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product @@ -6441,7 +7007,7 @@ Wormhole supports many blockchains across mainnet, testnet, and devnets. You can --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ --- BEGIN CONTENT --- --- title: Testnet Faucets @@ -6522,4 +7088,158 @@ Don't let the need for testnet tokens get in the way of buildling your next grea | Sui | Sui Move VM | SUI | List of Faucets | +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- + +# Wormhole Formatted Addresses + +## Introduction + +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. + +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. + +## Platform-Specific Address Formats + +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: + +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | + +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. + +### Address Format Handling + +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: + +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` + +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. + +## Universal Address Methods + +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. + +Key functions: + + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format + + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` + + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address + + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` + + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform + + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` + + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations + + ```typescript + console.log(universalAddress.toString()); + ``` + +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. + +## Convert Between Native and Wormhole Formatted Addresses + +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. + +### Convert a Native Address to a Wormhole Formatted Address + +Example conversions for EVM and Solana: + +=== "EVM" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' +); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); + ``` + +=== "Solana" + + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; + +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` + +The result is a standardized address format that is ready for cross-chain operations. + +### Convert Back to Native Addresses + +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: + +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); + +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` + +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. + +## Use Cases for Wormhole Formatted Addresses + +### Cross-chain Token Transfers + +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. + +### Smart Contract Interactions + +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. + +### DApp Development + +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. + +### Relayers and Infrastructure + +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. --- END CONTENT --- \ No newline at end of file diff --git a/llms-full.txt b/llms-full.txt index 09f2b00f6..63104a10b 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -6,23538 +6,23647 @@ Wormhole. A cross-chain messaging protocol used to move data and assets between Documentation: https://wormhole.com/docs/ ## List of doc pages: -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/core-contracts.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/wormhole-relayers.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers/run-relayer.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/spy/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/spy/run-spy.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-evm.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-solana.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/faq.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-evm.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-solana.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/faqs.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/overview.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/use-queries.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/chain-ids.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/consistency-levels.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/contract-addresses.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/wormhole-formatted-addresses.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/products.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/supported-networks.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/testnet-faucets.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/use-cases.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/cli.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/dev-env.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/faqs.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/solidity-sdk.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/protocols-payloads.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/sdk-layout.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/vaas-protocols.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/wormhole-sdk.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/cctp.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration-v0.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-data.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-theme.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/faqs.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/features.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/overview.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/routes.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/upgrade.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/cli-commands.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/access-control.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/rate-limiting.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/installation.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/post-deployment.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/troubleshooting.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/faqs.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/managers-transceivers.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/faqs.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/liquidity-layer.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/solver.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/token-bridge.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/glossary.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/architecture.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/faq.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/overview.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/architecture.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/core-contracts.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/guardians.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/relayer.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/spy.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/vaas.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/introduction.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/security.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/cctp.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/architecture.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/deployment.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/overview.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/security.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/architecture.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/overview.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/token-bridge.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/react-dapp.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multichain-assets/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multichain-assets/multichain-token.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov/treasury-proposal.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/settlement/.index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/settlement/.settlement-routes.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/cross-chain-contracts.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/cross-chain-token-contracts.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/tokens-via-token-bridge.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/usdc-via-cctp.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/wormholescan/index.md -Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/wormholescan/replace-signatures.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/ai-resources/ai-resources.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/guides/cctp-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/tutorials/complete-usdc-transfer.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/concepts/routes.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/configuration-v0.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/data.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/theme.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/hosted-version.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/upgrade.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/reference/support-matrix.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/tutorials/react-dapp.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/core-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/wormhole-relayers.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/cross-chain-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/cross-chain-token-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/replace-signatures.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/concepts/architecture.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-evm.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-solana.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-evm.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-solana.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/tutorials/treasury-proposal.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/architecture.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/security.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/access-control.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/rate-limiting.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-evm.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-solana.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/evm-launchpad.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/post-deployment.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/troubleshoot.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/cli-commands.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/managers-transceivers.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/products.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/guides/use-queries.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-methods.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-networks.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/chain-ids.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/consistency-levels.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/contract-addresses.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/glossary.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/supported-networks.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/testnet-faucets.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/wormhole-formatted-addresses.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/concepts/architecture.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/payload-structure.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/transfer-flow.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/guides/token-bridge-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/overview.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/tutorials/multichain-token.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/tutorials/transfer-workflow.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/architecture.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/ecosystem.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure-guides/run-relayer.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure-guides/run-spy.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/core-contracts.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/guardians.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/relayer.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/spy.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/vaas.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/introduction.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/security.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/cli/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/dev-env.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/faqs.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/sdk-reference.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/get-started.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/protocols-payloads.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/sdk-layout.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/vaas-protocols.md +Doc-Page: https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/sdk-reference.md ## Full content for each doc page -Doc-Content: https://wormhole.com/docs/build/core-messaging/core-contracts/ +Doc-Content: https://wormhole.com/docs/ai-resources/ai-resources/ --- BEGIN CONTENT --- --- -title: Get Started with Core Contracts -description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -categories: Basics +title: AI Resources +description: Download LLM-optimized files of the Wormhole documentation, including full content and category-specific resources for AI agents. --- -# Get Started with Core Contracts +# AI Resources +Wormhole provides `.txt` files containing the documentation content and navigation structure, optimized for use with large language models (LLMs) and AI tools. These resources help build AI assistants, power code search, or enable custom tooling trained on Wormhole’s docs. + +Each category file includes foundational content from the **Basics** and **Reference** categories to ensure LLMs have the necessary context. + +## Download LLM Files + + +| Category | Description | File | Actions | +|----------------|-------------------|-------|----------| +| Index | Navigation index of all Wormhole documentation pages | `llms.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms.txt" } [:octicons-download-16:](/docs/llms.txt){ download="llms.txt" } | +| Full Documentation | Full content of all documentation pages | `llms-full.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-full.txt" } [:octicons-download-16:](/docs/llms-full.txt){ download="llms-full.txt" } | +| Basics | Wormhole's architecture, security, and core components to help understand how the protocol works | `llms-basics.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-basics.txt" } [:octicons-download-16:](/docs/llms-files/llms-basics.txt){ download="llms-basics.txt" } | +| Reference | Reference details such as chain IDs, contract addresses, and finality levels | `llms-reference.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-reference.txt"} [:octicons-download-16:](/docs/llms-files/llms-reference.txt){ download="llms-reference.txt" } | +| NTT | All NTT docs, including architecture, deployment guides, CLI usage, and configuration for EVM and Solana | `llms-ntt.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-ntt.txt" } [:octicons-download-16:](/docs/llms-files/llms-ntt.txt){ download="llms-ntt.txt" } | +| Connect | Setup, features, and configuration details for integrating the Connect widget into your dApp | `llms-connect.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-connect.txt" } [:octicons-download-16:](/docs/llms-files/llms-connect.txt){ download="llms-connect.txt" } | +| Token Bridge | Architecture overview, transfer flows, and smart contract methods for cross-chain token transfers using the Token Bridge | `llms-token-bridge.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-token-bridge.txt" } [:octicons-download-16:](/docs/llms-files/llms-token-bridge.txt){ download="llms-token-bridge.txt" } | +| Settlement | Architecture, integration guides, and setup instructions for building on the Wormhole Settlement protocol | `llms-settlement.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-settlement.txt" } [:octicons-download-16:](/docs/llms-files/llms-settlement.txt){ download="llms-settlement.txt" } | +| Relayers | Guides and reference for using Wormhole’s Relayer module, building cross-chain messaging contracts, and running custom relayers | `llms-relayers.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-relayers.txt" } [:octicons-download-16:](/docs/llms-files/llms-relayers.txt){ download="llms-relayers.txt" } | +| MultiGov | Architecture, deployment steps, and upgrade instructions for multichain governance on EVM and Solana | `llms-multigov.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-multigov.txt" } [:octicons-download-16:](/docs/llms-files/llms-multigov.txt){ download="llms-multigov.txt" } | +| Queries | Guides for using the Wormhole Query SDK and Proxy to construct, test, and verify on-chain data queries across chains | `llms-queries.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-queries.txt" } [:octicons-download-16:](/docs/llms-files/llms-queries.txt){ download="llms-queries.txt" } | +| Solidity SDK | SDK docs for cross-chain messaging, token transfers, relayer integration, and local testing in Solidity | `llms-solidity-sdk.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-solidity-sdk.txt" } [:octicons-download-16:](/docs/llms-files/llms-solidity-sdk.txt){ download="llms-solidity-sdk.txt" } | +| TypeScript SDK | Docs for working with VAAs, payloads, and cross-chain message structures using the TypeScript SDK | `llms-typescript-sdk.txt` | [:octicons-copy-16:](){ .llms action="copy" data-value="llms-typescript-sdk.txt" } [:octicons-download-16:](/docs/llms-files/llms-typescript-sdk.txt){ download="llms-typescript-sdk.txt" } | + +!!! note + The `llms-full.txt` file may exceed the input limits of some language models due to its size. If you encounter limitations, consider using the files by category. +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with CCTP +description: Transfer USDC across chains using Wormhole's CCTP integration with the TypeScript SDK, including setup, attestation, and redemption steps. +categories: Transfer +--- + +# Get Started with CCTP ## Introduction -Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. +[Wormhole CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} enables native USDC transfers between supported chains by burning tokens on the source chain and minting them on the destination. This provides native, canonical USDC movement without the need for wrapped tokens. -While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. +In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform a manual cross-chain USDC transfer using Circle's CCTP protocol. -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +You will initiate the transfer on the source chain, wait for Circle's attestation, and redeem the USDC on the destination chain. ## Prerequisites -To interact with the Wormhole Core Contract, you'll need the following: - -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +Before you begin, make sure you have the following: -## How to Interact with Core Contracts + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with native tokens and USDC on two [supported CCTP chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: +This example uses an Avalanche Fuji wallet with [USDC](https://faucet.circle.com/){target=\_blank} and [AVAX](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank}, as well as a Sepolia wallet with testnet [ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank}, to pay the transaction fees. You can adapt the steps to work with any [supported EVM chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} that support CCTP. -- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication -- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network +## Configure Your Token Transfer Environment -While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. +1. Create a new directory and initialize a Node.js project: -### Sending Messages + ```bash + mkdir cctp-bridge + cd cctp-bridge + npm init -y + ``` -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +2. Install the required dependencies: -=== "EVM" + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` - The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: +3. Create a `transfer.ts` file to handle the multichain transfer logic and a `helper.ts` file to manage wallet signers: - ```solidity - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel -) external payable returns (uint64 sequence); + ```bash + touch transfer.ts helper.ts ``` - ??? interface "Parameters" +4. Set up secure access to your wallets. This guide assumes you are loading your `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. - `nonce` ++"uint32"++ - - A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. - --- +## Perform a CCTP Transfer - `payload` ++"bytes memory"++ - - The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. +This section walks you through a complete manual USDC transfer using Wormhole's CCTP integration. You will initiate the transfer on Avalanche Fuji, wait for the Circle attestation, and complete the redemption on Sepolia. - --- +Start by defining utility functions for signer and token setup: - `consistencyLevel` ++"uint8"++ - - A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. +1. In `helper.ts`, define functions to load private keys and instantiate EVM signers: - ??? interface "Returns" + ```ts title="helper.ts" + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; - `sequence` ++"uint64"++ - - A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. - - ??? interface "Example" +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` -// Check fee and send parameters +2. In `transfer.ts`, add the script to perform the manual transfer using CCTP: -// Create the HelloWorldMessage struct -HelloWorldMessage memory parsedMessage = HelloWorldMessage({ - payloadID: uint8(1), - message: helloWorldMessage -}); + ```ts title="transfer.ts" + import { CircleTransfer, wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { getSigner } from './helper'; -// Encode the HelloWorldMessage struct into bytes -bytes memory encodedMessage = encodeMessage(parsedMessage); +(async function () { + // Initialize the Wormhole object for the Testnet environment and add supported chains (evm, solana and sui) + const wh = await wormhole('Testnet', [evm, solana, sui]); -// Send the HelloWorld message by calling publishMessage on the -// wormhole core contract and paying the Wormhole protocol fee. -messageSequence = wormhole.publishMessage{value: wormholeFee}( - 0, // batchID - encodedMessage, - wormholeFinality() -); - ``` + // Grab chain Contexts -- these hold a reference to a cached rpc client + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Sepolia'); - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + // Get signer from local key + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -=== "Solana" + // Define the amount of USDC to transfer (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) + const amt = 100_000n; - The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: + const automatic = false; - ```rs - pub fn post_message<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, - batch_id: u32, - payload: Vec, - finality: Finality - ) -> Result<()> - ``` + // Create the circleTransfer transaction (USDC-only) + const xfer = await wh.circleTransfer( + amt, + source.address, + destination.address, + automatic + ); - ??? interface "Parameters" + const quote = await CircleTransfer.quoteTransfer( + sendChain, + rcvChain, + xfer.transfer + ); + console.log('Quote: ', quote); - `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ - - Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). + // Step 1: Initiate the transfer on the source chain (Avalanche) + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); - ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" + // Step 2: Wait for Circle Attestation (VAA) + const timeout = 120 * 1000; // Timeout in milliseconds (120 seconds) + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(timeout); + console.log(`Got Attestation: `, attestIds); - ```rs - pub struct CpiContext<'a, 'b, 'c, 'info, T> - where - T: ToAccountMetas + ToAccountInfos<'info>, - { - pub accounts: T, - pub remaining_accounts: Vec>, - pub program: AccountInfo<'info>, - pub signer_seeds: &'a [&'b [&'c [u8]]], - } - ``` + // Step 3: Complete the transfer on the destination chain (Sepolia) + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, dstTxids); - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. + process.exit(0); +})(); + ``` - ??? child "Type `PostMessage<'info>`" +3. Run the script to execute the transfer: - ```rs - pub struct PostMessage<'info> { - pub config: AccountInfo<'info>, - pub message: AccountInfo<'info>, - pub emitter: AccountInfo<'info>, - pub sequence: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub fee_collector: AccountInfo<'info>, - pub clock: AccountInfo<'info>, - pub rent: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - } - ``` + ```bash + npx tsx transfer.ts + ``` - For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. + You will see terminal output similar to the following: - --- +
+npx tsx transfer.ts +Starting Transfer +Started Transfer: + [ '0xdedbf496a1e658efb15bc57f120122b38a3714a560892be7a8c0a7f23c44aca2', + '0x9a8e41837e225edfa62d1913f850c01bd0552e55bf082fd9225df789455a465a' ] + +Waiting for Attestation +Retrying Circle:GetAttestation, attempt 0/60 +Retrying Circle:GetAttestation, attempt 1/60 + +Got Attestation: [{hash: '0x89f8651bf94cfd932ba5bcd2f7795a3fabc6a7c602075fa712c9c55022f5cca8'}] + +Completing Transfer +Completed Transfer: + [ '0x9b81bb30d2a68aa2ecc707a8a1b5af63448223a69b2ead6cf6d172ab880ad0c9'] + +
- `batch_id` ++"u32"++ - - An identifier for the message batch. +To verify the transaction and view its details, paste the transaction hash into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. - --- +## Next Steps - `payload` ++"Vec"++ - - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. +Now that you've completed a CCTP USDC transfer using the Wormhole SDK, you're ready to explore more advanced features and expand your integration: - --- + - [**Circle CCTP Documentation**](https://developers.circle.com/stablecoins/cctp-getting-started): Learn how USDC cross-chain transfers work and explore advanced CCTP features. +--- END CONTENT --- - `finality` ++"Finality"++ - - Specifies the level of finality or confirmation required for the message. - - ??? child "Type `Finality`" +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/guides/cctp-contracts/ +--- BEGIN CONTENT --- +--- +title: Interacting with CCTP Contracts +description: Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. +categories: Transfer +--- - ```rs - pub enum Finality { - Confirmed, - Finalized, - } - ``` - - ??? interface "Returns" +# Interact with CCTP Contracts - ++"Result<()>"++ - - The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error - - ??? interface "Example" +## Introduction - ```rust - let fee = ctx.accounts.wormhole_bridge.fee(); -// ... Check fee and send parameters +Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/products/cctp-bridge/overview/){target=\_blank} is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. -let config = &ctx.accounts.config -let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; +As decentralized finance (DeFi) protocols evolve, the need for flexible, secure cross-chain messaging has expanded, requiring solutions beyond simple asset transfers. Wormhole enhances CCTP's capabilities by allowing developers to compose more complex cross-chain interactions. With Wormhole's generic messaging, applications can execute smart contract logic alongside native USDC transfers, enabling richer, more versatile cross-chain experiences. -// Invoke `wormhole::post_message`. -wormhole::post_message( - CpiContext::new_with_signer( - ctx.accounts.wormhole_program.to_account_info(), - wormhole::PostMessage { - // ... Set fields - }, - &[ - // ... Set seeds - ], - ), - config.batch_id, - payload, - config.finality.into(), -)?; - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +This guide will walk you through getting started with Wormhole's CCTP contracts and show you how to integrate CCTP into your smart contracts, enabling the composition of advanced cross-chain functions with native USDC transfers. -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +## Prerequisites -### Receiving Messages +To interact with the Wormhole CCTP, you'll need the following: -The way a message is received and handled depends on the environment. +- [The address of the CCTP contract](/docs/products/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -=== "EVM" +## Wormhole's CCTP Integration Contract - On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. +Wormhole's Circle Integration contract, `CircleIntegration.sol`, is the contract you'll interact with directly. It burns and mints Circle-supported tokens by using [Circle's CCTP contracts](#circles-cctp-contracts). - ```solidity - function parseAndVerifyVM( - bytes calldata encodedVM -) external view returns (VM memory vm, bool valid, string memory reason); - ``` +The Circle Integration contract emits Wormhole messages with arbitrary payloads to allow additional composability when performing cross-chain transfers of Circle-supported assets. - ??? interface "Parameters" +This contract can be found in [Wormhole's `wormhole-circle-integration` repository](https://github.com/wormhole-foundation/wormhole-circle-integration/){target=\_blank} on GitHub. - `encodedVM` ++"bytes calldata"++ - - The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. +!!! note + Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/products/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. - ??? interface "Returns" +??? code "Circle Integration contract" + ```solidity + // SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.19; - `vm` ++"VM memory"++ - - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IWormhole} from "wormhole/interfaces/IWormhole.sol"; +import {BytesLib} from "wormhole/libraries/external/BytesLib.sol"; - ??? child "Struct `VM`" +import {ICircleBridge} from "../interfaces/circle/ICircleBridge.sol"; - ```solidity - struct VM { - uint8 version; - uint32 timestamp; - uint32 nonce; - uint16 emitterChainId; - bytes32 emitterAddress; - uint64 sequence; - uint8 consistencyLevel; - bytes payload; - uint32 guardianSetIndex; - Signature[] signatures; - bytes32 hash; - } - ``` +import {CircleIntegrationGovernance} from "./CircleIntegrationGovernance.sol"; +import {CircleIntegrationMessages} from "./CircleIntegrationMessages.sol"; - For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. +/** + * @notice This contract burns and mints Circle-supported tokens by using Circle's Cross-Chain Transfer Protocol. It also emits + * Wormhole messages with arbitrary payloads to allow for additional composability when performing cross-chain + * transfers of Circle-suppored assets. + */ +contract CircleIntegration is + CircleIntegrationMessages, + CircleIntegrationGovernance, + ReentrancyGuard +{ + using BytesLib for bytes; - --- - - `valid` ++"bool"++ - - A boolean indicating whether the VAA is valid or not. - - --- + /** + * @notice Emitted when Circle-supported assets have been minted to the mintRecipient + * @param emitterChainId Wormhole chain ID of emitter contract on source chain + * @param emitterAddress Address (bytes32 zero-left-padded) of emitter on source chain + * @param sequence Sequence of Wormhole message used to mint tokens + */ + event Redeemed( + uint16 indexed emitterChainId, + bytes32 indexed emitterAddress, + uint64 indexed sequence + ); - `reason` ++"string"++ - - If the VAA is not valid, a reason will be provided + /** + * @notice `transferTokensWithPayload` calls the Circle Bridge contract to burn Circle-supported tokens. It emits + * a Wormhole message containing a user-specified payload with instructions for what to do with + * the Circle-supported assets once they have been minted on the target chain. + * @dev reverts if: + * - user passes insufficient value to pay Wormhole message fee + * - `token` is not supported by Circle Bridge + * - `amount` is zero + * - `targetChain` is not supported + * - `mintRecipient` is bytes32(0) + * @param transferParams Struct containing the following attributes: + * - `token` Address of the token to be burned + * - `amount` Amount of `token` to be burned + * - `targetChain` Wormhole chain ID of the target blockchain + * - `mintRecipient` The recipient wallet or contract address on the target chain + * @param batchId ID for Wormhole message batching + * @param payload Arbitrary payload to be delivered to the target chain via Wormhole + * @return messageSequence Wormhole sequence number for this contract + */ + function transferTokensWithPayload( + TransferParameters memory transferParams, + uint32 batchId, + bytes memory payload + ) public payable nonReentrant returns (uint64 messageSequence) { + // cache wormhole instance and fees to save on gas + IWormhole wormhole = wormhole(); + uint256 wormholeFee = wormhole.messageFee(); - ??? interface "Example" + // confirm that the caller has sent enough ether to pay for the wormhole message fee + require(msg.value == wormholeFee, "insufficient value"); - ```solidity - function receiveMessage(bytes memory encodedMessage) public { - // Call the Wormhole core contract to parse and verify the encodedMessage - ( - IWormhole.VM memory wormholeMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + // Call the circle bridge and `depositForBurnWithCaller`. The `mintRecipient` + // should be the target contract (or wallet) composing on this contract. + (uint64 nonce, uint256 amountReceived) = _transferTokens{value: wormholeFee}( + transferParams.token, + transferParams.amount, + transferParams.targetChain, + transferParams.mintRecipient + ); - // Perform safety checks here + // encode DepositWithPayload message + bytes memory encodedMessage = encodeDepositWithPayload( + DepositWithPayload({ + token: addressToBytes32(transferParams.token), + amount: amountReceived, + sourceDomain: localDomain(), + targetDomain: getDomainFromChainId(transferParams.targetChain), + nonce: nonce, + fromAddress: addressToBytes32(msg.sender), + mintRecipient: transferParams.mintRecipient, + payload: payload + }) + ); - // Decode the message payload into the HelloWorldMessage struct - HelloWorldMessage memory parsedMessage = decodeMessage( - wormholeMessage.payload - ); + // send the DepositWithPayload wormhole message + messageSequence = wormhole.publishMessage{value: wormholeFee}( + batchId, + encodedMessage, + wormholeFinality() + ); + } - // Your custom application logic here -} - ``` + function _transferTokens( + address token, + uint256 amount, + uint16 targetChain, + bytes32 mintRecipient + ) internal returns (uint64 nonce, uint256 amountReceived) { + // sanity check user input + require(amount > 0, "amount must be > 0"); + require(mintRecipient != bytes32(0), "invalid mint recipient"); + require(isAcceptedToken(token), "token not accepted"); + require( + getRegisteredEmitter(targetChain) != bytes32(0), + "target contract not registered" + ); - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. + // take custody of tokens + amountReceived = custodyTokens(token, amount); -=== "Solana" + // cache Circle Bridge instance + ICircleBridge circleBridge = circleBridge(); - On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. + // approve the Circle Bridge to spend tokens + SafeERC20.safeApprove( + IERC20(token), + address(circleBridge), + amountReceived + ); - Retrieve the raw message data: + // burn tokens on the bridge + nonce = circleBridge.depositForBurnWithCaller( + amountReceived, + getDomainFromChainId(targetChain), + mintRecipient, + token, + getRegisteredEmitter(targetChain) + ); + } - ```rs - let posted_message = &ctx.accounts.posted; - posted_message.data() - ``` + function custodyTokens( + address token, + uint256 amount + ) internal returns (uint256) { + // query own token balance before transfer + (, bytes memory queriedBalanceBefore) = token.staticcall( + abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)) + ); + uint256 balanceBefore = abi.decode(queriedBalanceBefore, (uint256)); - ??? interface "Example" + // deposit tokens + SafeERC20.safeTransferFrom( + IERC20(token), + msg.sender, + address(this), + amount + ); - ```rust - pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { - let posted_message = &ctx.accounts.posted + // query own token balance after transfer + (, bytes memory queriedBalanceAfter) = token.staticcall( + abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)) + ); + uint256 balanceAfter = abi.decode(queriedBalanceAfter, (uint256)); - if let HelloWorldMessage::Hello { message } = posted_message.data() { - // Check message - // Your custom application logic here - Ok(()) - } else { - Err(HelloWorldError::InvalidMessage.into()) + return balanceAfter - balanceBefore; } -} - - ``` - - View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - -#### Validating the Emitter - -When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: + /** + * @notice `redeemTokensWithPayload` verifies the Wormhole message from the source chain and + * verifies that the passed Circle Bridge message is valid. It calls the Circle Bridge + * contract by passing the Circle message and attestation to mint tokens to the specified + * mint recipient. It also verifies that the caller is the specified mint recipient to ensure + * atomic execution of the additional instructions in the Wormhole message. + * @dev reverts if: + * - Wormhole message is not properly attested + * - Wormhole message was not emitted from a registered contrat + * - Wormhole message was already consumed by this contract + * - msg.sender is not the encoded mintRecipient + * - Circle Bridge message and Wormhole message are not associated + * - `receiveMessage` call to Circle Transmitter fails + * @param params Struct containing the following attributes: + * - `encodedWormholeMessage` Wormhole message emitted by a registered contract including + * information regarding the token burn on the source chain and an arbitrary message. + * - `circleBridgeMessage` Message emitted by Circle Bridge contract with information regarding + * the token burn on the source chain. + * - `circleAttestation` Serialized EC Signature attesting the cross-chain transfer + * @return depositInfo Struct containing the following attributes: + * - `token` Address (bytes32 left-zero-padded) of token to be minted + * - `amount` Amount of tokens to be minted + * - `sourceDomain` Circle domain for the source chain + * - `targetDomain` Circle domain for the target chain + * - `nonce` Circle sequence number for the transfer + * - `fromAddress` Source CircleIntegration contract caller's address + * - `mintRecipient` Recipient of minted tokens (must be caller of this contract) + * - `payload` Arbitrary Wormhole message payload + */ + function redeemTokensWithPayload( + RedeemParameters calldata params + ) public returns (DepositWithPayload memory depositInfo) { + // verify the wormhole message + IWormhole.VM memory verifiedMessage = verifyWormholeRedeemMessage( + params.encodedWormholeMessage + ); -```solidity -require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); -``` + // Decode the message payload into the DepositWithPayload struct. Call the Circle TokenMinter + // contract to determine the address of the encoded token on this chain. + depositInfo = decodeDepositWithPayload(verifiedMessage.payload); + depositInfo.token = fetchLocalTokenAddress( + depositInfo.sourceDomain, + depositInfo.token + ); -This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. + // confirm that circle gave us a valid token address + require(depositInfo.token != bytes32(0), "invalid local token address"); -```typescript -const tx = await receiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) -); + // confirm that the caller is the `mintRecipient` to ensure atomic execution + require( + addressToBytes32(msg.sender) == depositInfo.mintRecipient, + "caller must be mintRecipient" + ); -await tx.wait(); -``` + // confirm that the caller passed the correct message pair + require( + verifyCircleMessage( + params.circleBridgeMessage, + depositInfo.sourceDomain, + depositInfo.targetDomain, + depositInfo.nonce + ), + "invalid message pair" + ); -#### Additional Checks + // call the circle bridge to mint tokens to the recipient + bool success = circleTransmitter().receiveMessage( + params.circleBridgeMessage, + params.circleAttestation + ); + require(success, "CIRCLE_INTEGRATION: failed to mint tokens"); -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: + // emit Redeemed event + emit Redeemed( + verifiedMessage.emitterChainId, + verifiedMessage.emitterAddress, + verifiedMessage.sequence + ); + } -- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? + function verifyWormholeRedeemMessage( + bytes memory encodedMessage + ) internal returns (IWormhole.VM memory) { + require(evmChain() == block.chainid, "invalid evm chain"); -The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. + // parse and verify the Wormhole core message + ( + IWormhole.VM memory verifiedMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -## Source Code References + // confirm that the core layer verified the message + require(valid, reason); -For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: + // verify that this message was emitted by a trusted contract + require(verifyEmitter(verifiedMessage), "unknown emitter"); -- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} -- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} -- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) -- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} -- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} -- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} -- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} ---- END CONTENT --- + // revert if this message has been consumed already + require( + !isMessageConsumed(verifiedMessage.hash), + "message already consumed" + ); + consumeMessage(verifiedMessage.hash); -Doc-Content: https://wormhole.com/docs/build/core-messaging/ ---- BEGIN CONTENT --- ---- -title: Core Messaging Layer Contracts -description: Learn to use Wormhole’s foundational messaging contracts to build multichain apps with direct control over publishing, verifying, relaying, and more. ---- + return verifiedMessage; + } -# Core Messaging + function verifyEmitter( + IWormhole.VM memory vm + ) internal view returns (bool) { + // verify that the sender of the wormhole message is a trusted + return (getRegisteredEmitter(vm.emitterChainId) == vm.emitterAddress && + vm.emitterAddress != bytes32(0)); + } -Wormhole-deployed relayers and Core Contracts are essential for sending and receiving multichain messages. Learning to work directly with these building blocks offers a deeper understanding of Wormhole and increased control and customization options. + function verifyCircleMessage( + bytes memory circleMessage, + uint32 sourceDomain, + uint32 targetDomain, + uint64 nonce + ) internal pure returns (bool) { + // parse the circle bridge message inline + uint32 circleSourceDomain = circleMessage.toUint32(4); + uint32 circleTargetDomain = circleMessage.toUint32(8); + uint64 circleNonce = circleMessage.toUint64(12); -Follow the links below for how-to guides about using Core Contracts and Wormhole-deployed relayers to send, receive, validate, and track multichain messages. + // confirm that both the Wormhole message and Circle message share the same transfer info + return (sourceDomain == circleSourceDomain && + targetDomain == circleTargetDomain && + nonce == circleNonce); + } -## Simplified Message Flow + /** + * @notice Fetches the local token address given an address and domain from + * a different chain. + * @param sourceDomain Circle domain for the sending chain. + * @param sourceToken Address of the token for the sending chain. + * @return Address bytes32 formatted address of the `sourceToken` on this chain. + */ + function fetchLocalTokenAddress( + uint32 sourceDomain, + bytes32 sourceToken + ) public view returns (bytes32) { + return + addressToBytes32( + circleTokenMinter().remoteTokensToLocalTokens( + keccak256(abi.encodePacked(sourceDomain, sourceToken)) + ) + ); + } + /** + * @notice Converts type address to bytes32 (left-zero-padded) + * @param address_ Address to convert to bytes32 + * @return Address bytes32 + */ + function addressToBytes32(address address_) public pure returns (bytes32) { + return bytes32(uint256(uint160(address_))); + } +} + ``` -Wormhole-deployed relayer support is limited to EVM environments. For a complete list of supported EVM environment blockchains, see the [Supported Networks](/docs/build/start-building/supported-networks/){target=\_blank} page. +The functions provided by the Circle Integration contract are as follows: -[timeline(wormhole-docs/.snippets/text/build/core-messaging/core-messaging-timeline.json)] +- **`transferTokensWithPayload`** - calls the Circle Bridge contract to burn Circle-supported tokens. It emits a Wormhole message containing a user-specified payload with instructions for what to do with the Circle-supported assets once they have been minted on the target chain -## Next Steps + ??? interface "Parameters" -
+ `transferParams` ++"TransferParameters"++ -- :octicons-tools-16:{ .lg .middle} **Get Started with Core Contracts** + A tuple containing the parameters for the transfer. - --- + ??? child "`TransferParameters` struct" - Follow this series of how-to guides about interacting with Core Contracts to send, receive, and validate messages. + `token` ++"address"++ - [:custom-arrow: Get started](/docs/build/core-messaging/core-contracts/#prerequisites) + Address of the token to be burned. -- :octicons-tools-16:{ .lg .middle } **Get Started with Relayers** + --- - --- + `amount` ++"uint256"++ - Follow this series of how-to guides about using Wormhole-deployed relayers to send, receive, and track the progress of messages. + Amount of the token to be burned. - [:custom-arrow: Get started](/docs/build/core-messaging/wormhole-relayers/#get-started-with-the-wormhole-relayer) + --- -
---- END CONTENT --- + `targetChain` ++"uint16"++ -Doc-Content: https://wormhole.com/docs/build/core-messaging/wormhole-relayers/ ---- BEGIN CONTENT --- ---- -title: Wormhole-Deployed Relayers -description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -categories: Relayers, Basics ---- + Wormhole chain ID of the target blockchain. -# Wormhole Relayer + --- -## Introduction + `mintRecipient` ++"bytes32"++ -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. + The recipient wallet or contract address on the target chain. -This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. + --- -## Get Started with the Wormhole Relayer + `batchId` ++"uint32"++ -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. + The ID for Wormhole message batching. -To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. + --- -
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) -
The components outlined in blue must be implemented.
-
+ `payload` ++"bytes"++ -### Wormhole Relayer Interfaces + Arbitrary payload to be delivered to the target chain via Wormhole. -There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: + ??? interface "Returns" -- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs -- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract -- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from + `messageSequence` ++"uint64"++ -## Interact with the Wormhole Relayer + Wormhole sequence number for this contract. -To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. +- `redeemTokensWithPayload` - verifies the Wormhole message from the source chain and verifies that the passed Circle Bridge message is valid. It calls the Circle Bridge contract by passing the Circle message and attestation to the `receiveMessage` function, which is responsible for minting tokens to the specified mint recipient. It also verifies that the caller is the specified mint recipient to ensure atomic execution of the additional instructions in the Wormhole message -To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. + ??? interface "Parameters" -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. + `params` ++"RedeemParameters"++ -Your initial set up should resemble the following: + A tuple containing the parameters for the redemption. -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; + ??? child "`RedeemParameters` struct" -import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; + `encodedWormholeMessage` ++"bytes"++ -contract Example { - IWormholeRelayer public wormholeRelayer; + Wormhole message emitted by a registered contract including information regarding the token burn on the source chain and an arbitrary message. - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } -} -``` + --- -The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. + `circleBridgeMessage` ++"bytes"++ -### Send a Message + Message emitted by Circle Bridge contract with information regarding the token burn on the source chain. -To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. + --- -```solidity -function sendPayloadToEvm( - // Chain ID in Wormhole format - uint16 targetChain, - // Contract Address on target chain we're sending a message to - address targetAddress, - // The payload, encoded as bytes - bytes memory payload, - // How much value to attach to the delivery transaction - uint256 receiverValue, - // The gas limit to set on the delivery transaction - uint256 gasLimit -) external payable returns ( - // Unique, incrementing ID, used to identify a message - uint64 sequence -); -``` + `circleAttestation` ++"bytes"++ -!!! tip - To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. + Serialized EC signature attesting the cross-chain transfer. -The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. + ??? interface "Returns" -```solidity -function quoteEVMDeliveryPrice( - // Chain ID in Wormhole format - uint16 targetChain, - // How much value to attach to delivery transaction - uint256 receiverValue, - // The gas limit to attach to the delivery transaction - uint256 gasLimit -) external view returns ( - // How much value to attach to the send call - uint256 nativePriceQuote, - uint256 targetChainRefundPerGasUnused -); -``` + `depositInfo` ++"DepositWithPayload"++ -This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. + Information about the deposit. -In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: + ??? child "`DepositWithPayload` struct" -```solidity -// Get a quote for the cost of gas for delivery -(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - valueToSend, - GAS_LIMIT -); + `token` ++"bytes32"++ -// Send the message -wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(payload), - valueToSend, - GAS_LIMIT -); -``` + Address (`bytes32` left-zero-padded) of token to be minted. -### Receive a Message + --- -To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). + `amount` ++"uint256"++ -```solidity -function receiveWormholeMessages( - bytes memory payload, // Message passed by source contract - bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) - bytes32 sourceAddress, // The address of the source contract - uint16 sourceChain, // The Wormhole chain ID - bytes32 deliveryHash // A hash of contents, useful for replay protection -) external payable; -``` + Amount of tokens to be minted. + + --- -The logic inside the function body may be whatever business logic is required to take action on the specific payload. + `sourceDomain` ++"uint32"++ -## Delivery Guarantees + Circle domain for the source chain. -The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. + --- -This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. + `targetDomain` ++"uint32"++ -Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. + Circle domain for the target chain. -## Delivery Statuses + --- -All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: + `nonce` ++"uint64"++ -- (0) Delivery Success -- (1) Receiver Failure -- (2) Forward Request Success -- (3) Forward Request Failure + Circle sequence number for the transfer. -A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: + --- -- The target contract does not implement the `IWormholeReceiver` interface -- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` -- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` + `fromAddress` ++"bytes32"++ -All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. + Source Circle Integration contract caller's address. -`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. + --- -## Other Considerations + `mintRecipient` ++"bytes32"++ -Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: + Recipient of minted tokens (must be caller of this contract). -- Receiving a message from a relayer -- Checking for expected emitter -- Calling `parseAndVerify` on any additional VAAs -- Replay protection -- Message ordering (no guarantees on order of messages delivered) -- Forwarding and call chaining -- Refunding overpayment of `gasLimit` -- Refunding overpayment of value sent + --- -## Track the Progress of Messages with the Wormhole CLI + `payload` ++"bytes"++ -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: + Arbitrary Wormhole message payload. -=== "Mainnet" + ??? interface "Emits" - ```bash - worm status mainnet ethereum INSERT_TRANSACTION_HASH - ``` + `Redeemed` - event emitted when Circle-supported assets have been minted to the `mintRecipient` -=== "Testnet" + ??? child "Event arguments" - ```bash - worm status testnet ethereum INSERT_TRANSACTION_HASH - ``` + `emitterChainId` ++"uint16"++ -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. + Wormhole chain ID of emitter contract on source chain. -## Step-by-Step Tutorial + --- -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. ---- END CONTENT --- + `emitterAddress` ++"bytes32"++ -Doc-Content: https://wormhole.com/docs/build/ ---- BEGIN CONTENT --- ---- -title: Build with Wormhole -description: Learn how to start building multichain solutions on Wormhole, with tips to get started, an overview of the toolkit, and an introduction to the protocols. -template: root-index-page.html ---- + Address (`bytes32` zero-left-padded) of emitter on source chain. -# Build + --- -## Quick Start: Step-by-Step Tutorials + `sequence` ++"uint64"++ -If you learn best by building, start here to build with the Wormhole TypeScript SDK: + Sequence of Wormhole message used to mint tokens. -- [**Transfer Tokens via the Token Bridge**](/docs/tutorials/typescript-sdk/tokens-via-token-bridge/){target=\_blank} - use the [Wormhole SDK's](/docs/build/toolkit/typescript-sdk/){target=\_blank} Token Bridge method to move wrapped assets across networks +## Circle's CCTP Contracts -- [**Transfer USDC via CCTP and Wormhole SDK**](/docs/tutorials/typescript-sdk/usdc-via-cctp/){target=\_blank} - combine the [Wormhole SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} and Circle's Cross-Chain Transfer Protocol (CCTP) to bridge native USDC across networks +Three key contracts power Circle's CCTP: -Alternatively, start here to work with Wormhole contracts directly: +- **`TokenMessenger`** - the entry point for cross-chain USDC transfers, routing messages to initiate USDC burns on the source chain, and mint USDC on the destination chain +- **`MessageTransmitter`** - handles generic message passing, sending messages from the source chain and receiving them on the destination chain +- **`TokenMinter`** - responsible for the actual minting and burning of USDC, utilizing chain-specific settings for both the burners and minters across different networks -- [**Create Multichain Messaging Contracts**](/docs/tutorials/solidity-sdk/cross-chain-contracts/) - create mulitchain contracts using Wormhole's Solidity SDK. You will deploy smart contracts and send messages across chains +The following sections will examine these contracts in-depth, focusing on the methods invoked indirectly through function calls in the Wormhole Circle Integration contract. -- [**Create Multichain Token Transfer Contracts**](/docs/tutorials/solidity-sdk/cross-chain-token-contracts/) - create multichain token transfers using Wormhole's Solidity SDK. You will build and deploy smart contracts to send tokens from one blockchain to another +!!! note + When using Wormhole's CCTP integration, you will not directly interact with these contracts. You will indirectly interact with them through the Wormhole Circle Integration contract. -## Builder Essentials +These contracts can be found in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/){target=\_blank} on GitHub. -Access essential information and tools quickly: +### Token Messenger Contract -
+The Token Messenger contract enables cross-chain USDC transfers by coordinating message exchanges between blockchains. It works alongside the Message Transmitter contract to relay messages for burning USDC on a source chain and minting it on a destination chain. The contract emits events to track both the burning of tokens and their subsequent minting on the destination chain. -- :octicons-tools-16:{ .lg .middle } **Supported Networks** +To ensure secure communication, the Token Messenger restricts message handling to registered remote Token Messenger contracts only. It verifies the proper conditions for token burning and manages local and remote minters using chain-specific settings. - --- +Additionally, the contract provides methods for updating or replacing previously sent burn messages, adding or removing remote Token Messenger contracts, and managing the minting process for cross-chain transfers. - Supported blockchains by environment - main or testnet availability and quick links to the website, documentation, and block explorer for each network. +??? code "Token Messenger contract" + ```solidity + /* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity 0.7.6; - [:custom-arrow: Supported Networks](/docs/build/start-building/supported-networks/) +import "./interfaces/IMessageHandler.sol"; +import "./interfaces/ITokenMinter.sol"; +import "./interfaces/IMintBurnToken.sol"; +import "./interfaces/IMessageTransmitter.sol"; +import "./messages/BurnMessage.sol"; +import "./messages/Message.sol"; +import "./roles/Rescuable.sol"; -- :octicons-tools-16:{ .lg .middle } **Testnet Faucets** +/** + * @title TokenMessenger + * @notice Sends messages and receives messages to/from MessageTransmitters + * and to/from TokenMinters + */ +contract TokenMessenger is IMessageHandler, Rescuable { + // ============ Events ============ + /** + * @notice Emitted when a DepositForBurn message is sent + * @param nonce unique nonce reserved by message + * @param burnToken address of token burnt on source domain + * @param amount deposit amount + * @param depositor address where deposit is transferred from + * @param mintRecipient address receiving minted tokens on destination domain as bytes32 + * @param destinationDomain destination domain + * @param destinationTokenMessenger address of TokenMessenger on destination domain as bytes32 + * @param destinationCaller authorized caller as bytes32 of receiveMessage() on destination domain, if not equal to bytes32(0). + * If equal to bytes32(0), any address can call receiveMessage(). + */ + event DepositForBurn( + uint64 indexed nonce, + address indexed burnToken, + uint256 amount, + address indexed depositor, + bytes32 mintRecipient, + uint32 destinationDomain, + bytes32 destinationTokenMessenger, + bytes32 destinationCaller + ); - --- + /** + * @notice Emitted when tokens are minted + * @param mintRecipient recipient address of minted tokens + * @param amount amount of minted tokens + * @param mintToken contract address of minted token + */ + event MintAndWithdraw( + address indexed mintRecipient, + uint256 amount, + address indexed mintToken + ); - Links to testnet token faucets for supported networks. + /** + * @notice Emitted when a remote TokenMessenger is added + * @param domain remote domain + * @param tokenMessenger TokenMessenger on remote domain + */ + event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger); - [:custom-arrow: Get Testnet Tokens](/docs/build/start-building/testnet-faucets/) + /** + * @notice Emitted when a remote TokenMessenger is removed + * @param domain remote domain + * @param tokenMessenger TokenMessenger on remote domain + */ + event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger); -- :octicons-tools-16:{ .lg .middle } **Wormhole TypeScript SDK** + /** + * @notice Emitted when the local minter is added + * @param localMinter address of local minter + * @notice Emitted when the local minter is added + */ + event LocalMinterAdded(address localMinter); - --- + /** + * @notice Emitted when the local minter is removed + * @param localMinter address of local minter + * @notice Emitted when the local minter is removed + */ + event LocalMinterRemoved(address localMinter); - Your guide to Wormhole SDK installation and usage, concepts overview, and code samples. + // ============ Libraries ============ + using TypedMemView for bytes; + using TypedMemView for bytes29; + using BurnMessage for bytes29; + using Message for bytes29; - [:custom-arrow: Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/wormhole-sdk/) + // ============ State Variables ============ + // Local Message Transmitter responsible for sending and receiving messages to/from remote domains + IMessageTransmitter public immutable localMessageTransmitter; -- :octicons-tools-16:{ .lg .middle } **Reference** + // Version of message body format + uint32 public immutable messageBodyVersion; - --- - - Wormhole chain ID, contract address, address formatting and conversion, and consistency information. - - [:custom-arrow: Reference](/docs/build/reference/) - -
+ // Minter responsible for minting and burning tokens on the local domain + ITokenMinter public localMinter; -## Integrate Transfer Products + // Valid TokenMessengers on remote domains + mapping(uint32 => bytes32) public remoteTokenMessengers; -
+ // ============ Modifiers ============ + /** + * @notice Only accept messages from a registered TokenMessenger contract on given remote domain + * @param domain The remote domain + * @param tokenMessenger The address of the TokenMessenger contract for the given remote domain + */ + modifier onlyRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) { + require( + _isRemoteTokenMessenger(domain, tokenMessenger), + "Remote TokenMessenger unsupported" + ); + _; + } -- :octicons-tools-16:{ .lg .middle } **Multichain Transfers** + /** + * @notice Only accept messages from the registered message transmitter on local domain + */ + modifier onlyLocalMessageTransmitter() { + // Caller must be the registered message transmitter for this domain + require(_isLocalMessageTransmitter(), "Invalid message transmitter"); + _; + } - --- + // ============ Constructor ============ + /** + * @param _messageTransmitter Message transmitter address + * @param _messageBodyVersion Message body version + */ + constructor(address _messageTransmitter, uint32 _messageBodyVersion) { + require( + _messageTransmitter != address(0), + "MessageTransmitter not set" + ); + localMessageTransmitter = IMessageTransmitter(_messageTransmitter); + messageBodyVersion = _messageBodyVersion; + } - - **Connect UI widget** - easy-to-use UI for multichain asset transfers via Wormhole in a web application - - **Native Token Transfers (NTT)** - native asset transfer, without the need for wrapped assets - - **Token Bridge** - transfer wrapped assets with optional message payloads - - **Settlement** - intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more + // ============ External Functions ============ + /** + * @notice Deposits and burns tokens from sender to be minted on destination domain. + * Emits a `DepositForBurn` event. + * @dev reverts if: + * - given burnToken is not supported + * - given destinationDomain has no TokenMessenger registered + * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance + * to this contract is less than `amount`. + * - burn() reverts. For example, if `amount` is 0. + * - MessageTransmitter returns false or reverts. + * @param amount amount of tokens to burn + * @param destinationDomain destination domain + * @param mintRecipient address of mint recipient on destination domain + * @param burnToken address of contract to burn deposited tokens, on local domain + * @return _nonce unique nonce reserved by message + */ + function depositForBurn( + uint256 amount, + uint32 destinationDomain, + bytes32 mintRecipient, + address burnToken + ) external returns (uint64 _nonce) { + return + _depositForBurn( + amount, + destinationDomain, + mintRecipient, + burnToken, + // (bytes32(0) here indicates that any address can call receiveMessage() + // on the destination domain, triggering mint to specified `mintRecipient`) + bytes32(0) + ); + } - [:custom-arrow: Build Multichain Transfers](/docs/build/transfers/) + /** + * @notice Deposits and burns tokens from sender to be minted on destination domain. The mint + * on the destination domain must be called by `destinationCaller`. + * WARNING: if the `destinationCaller` does not represent a valid address as bytes32, then it will not be possible + * to broadcast the message on the destination domain. This is an advanced feature, and the standard + * depositForBurn() should be preferred for use cases where a specific destination caller is not required. + * Emits a `DepositForBurn` event. + * @dev reverts if: + * - given destinationCaller is zero address + * - given burnToken is not supported + * - given destinationDomain has no TokenMessenger registered + * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance + * to this contract is less than `amount`. + * - burn() reverts. For example, if `amount` is 0. + * - MessageTransmitter returns false or reverts. + * @param amount amount of tokens to burn + * @param destinationDomain destination domain + * @param mintRecipient address of mint recipient on destination domain + * @param burnToken address of contract to burn deposited tokens, on local domain + * @param destinationCaller caller on the destination domain, as bytes32 + * @return nonce unique nonce reserved by message + */ + function depositForBurnWithCaller( + uint256 amount, + uint32 destinationDomain, + bytes32 mintRecipient, + address burnToken, + bytes32 destinationCaller + ) external returns (uint64 nonce) { + // Destination caller must be nonzero. To allow any destination caller, use depositForBurn(). + require(destinationCaller != bytes32(0), "Invalid destination caller"); -
+ return + _depositForBurn( + amount, + destinationDomain, + mintRecipient, + burnToken, + destinationCaller + ); + } -## Access Real-Time Data + /** + * @notice Replace a BurnMessage to change the mint recipient and/or + * destination caller. Allows the sender of a previous BurnMessage + * (created by depositForBurn or depositForBurnWithCaller) + * to send a new BurnMessage to replace the original. + * The new BurnMessage will reuse the amount and burn token of the original, + * without requiring a new deposit. + * @dev The new message will reuse the original message's nonce. For a + * given nonce, all replacement message(s) and the original message are + * valid to broadcast on the destination domain, until the first message + * at the nonce confirms, at which point all others are invalidated. + * Note: The msg.sender of the replaced message must be the same as the + * msg.sender of the original message. + * @param originalMessage original message bytes (to replace) + * @param originalAttestation original attestation bytes + * @param newDestinationCaller the new destination caller, which may be the + * same as the original destination caller, a new destination caller, or an empty + * destination caller (bytes32(0), indicating that any destination caller is valid.) + * @param newMintRecipient the new mint recipient, which may be the same as the + * original mint recipient, or different. + */ + function replaceDepositForBurn( + bytes calldata originalMessage, + bytes calldata originalAttestation, + bytes32 newDestinationCaller, + bytes32 newMintRecipient + ) external { + bytes29 _originalMsg = originalMessage.ref(0); + _originalMsg._validateMessageFormat(); + bytes29 _originalMsgBody = _originalMsg._messageBody(); + _originalMsgBody._validateBurnMessageFormat(); -
+ bytes32 _originalMsgSender = _originalMsgBody._getMessageSender(); + // _originalMsgSender must match msg.sender of original message + require( + msg.sender == Message.bytes32ToAddress(_originalMsgSender), + "Invalid sender for message" + ); + require( + newMintRecipient != bytes32(0), + "Mint recipient must be nonzero" + ); -- :octicons-tools-16:{ .lg .middle } **Real-Time Data** + bytes32 _burnToken = _originalMsgBody._getBurnToken(); + uint256 _amount = _originalMsgBody._getAmount(); - --- + bytes memory _newMessageBody = BurnMessage._formatMessage( + messageBodyVersion, + _burnToken, + newMintRecipient, + _amount, + _originalMsgSender + ); - - **Wormhole Queries** - on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy - - **Supported query types** - includes query equivalents for `eth_call` (with options for timestamp and finality), `sol_account`, and `sol_pda` - - **Use familiar endpoints** - make calls against the RPC provider endpoints you already know and use + localMessageTransmitter.replaceMessage( + originalMessage, + originalAttestation, + _newMessageBody, + newDestinationCaller + ); - [:custom-arrow: Build with Queries](/docs/build/queries/) + emit DepositForBurn( + _originalMsg._nonce(), + Message.bytes32ToAddress(_burnToken), + _amount, + msg.sender, + newMintRecipient, + _originalMsg._destinationDomain(), + _originalMsg._recipient(), + newDestinationCaller + ); + } -
+ /** + * @notice Handles an incoming message received by the local MessageTransmitter, + * and takes the appropriate action. For a burn message, mints the + * associated token to the requested recipient on the local domain. + * @dev Validates the local sender is the local MessageTransmitter, and the + * remote sender is a registered remote TokenMessenger for `remoteDomain`. + * @param remoteDomain The domain where the message originated from. + * @param sender The sender of the message (remote TokenMessenger). + * @param messageBody The message body bytes. + * @return success Bool, true if successful. + */ + function handleReceiveMessage( + uint32 remoteDomain, + bytes32 sender, + bytes calldata messageBody + ) + external + override + onlyLocalMessageTransmitter + onlyRemoteTokenMessenger(remoteDomain, sender) + returns (bool) + { + bytes29 _msg = messageBody.ref(0); + _msg._validateBurnMessageFormat(); + require( + _msg._getVersion() == messageBodyVersion, + "Invalid message body version" + ); -## Multichain Governance + bytes32 _mintRecipient = _msg._getMintRecipient(); + bytes32 _burnToken = _msg._getBurnToken(); + uint256 _amount = _msg._getAmount(); -
+ ITokenMinter _localMinter = _getLocalMinter(); -- :octicons-tools-16:{ .lg .middle } **MultiGov** + _mintAndWithdraw( + address(_localMinter), + remoteDomain, + _burnToken, + Message.bytes32ToAddress(_mintRecipient), + _amount + ); - --- + return true; + } - - **Wormhole's MultiGov** - a multichain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks - - **Hub-and-spoke model** - spoke chain contracts handle local voting and proposals with results sent to the hub for vote aggregation and tallying, proposal management, and coordinating governance across connected chains - - **Wormhole security** - moving vote weight checkpoints, timelocks, and Wormhole verification keep governance activity secure + /** + * @notice Add the TokenMessenger for a remote domain. + * @dev Reverts if there is already a TokenMessenger set for domain. + * @param domain Domain of remote TokenMessenger. + * @param tokenMessenger Address of remote TokenMessenger as bytes32. + */ + function addRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) + external + onlyOwner + { + require(tokenMessenger != bytes32(0), "bytes32(0) not allowed"); - [:custom-arrow: Build with MultiGov](/docs/build/multigov/) + require( + remoteTokenMessengers[domain] == bytes32(0), + "TokenMessenger already set" + ); -
---- END CONTENT --- + remoteTokenMessengers[domain] = tokenMessenger; + emit RemoteTokenMessengerAdded(domain, tokenMessenger); + } -Doc-Content: https://wormhole.com/docs/build/infrastructure/ ---- BEGIN CONTENT --- ---- -title: Run Infrastructure Services -description: Follow the guides in this section to learn how to run off-chain infrastructure services, such as running a spy or a customized relayer. -# template: root-index-page.html ---- - -# Infrastructure + /** + * @notice Remove the TokenMessenger for a remote domain. + * @dev Reverts if there is no TokenMessenger set for `domain`. + * @param domain Domain of remote TokenMessenger + */ + function removeRemoteTokenMessenger(uint32 domain) external onlyOwner { + // No TokenMessenger set for given remote domain. + require( + remoteTokenMessengers[domain] != bytes32(0), + "No TokenMessenger set" + ); -## Get Started + bytes32 _removedTokenMessenger = remoteTokenMessengers[domain]; + delete remoteTokenMessengers[domain]; + emit RemoteTokenMessengerRemoved(domain, _removedTokenMessenger); + } -Follow the guides in this section to learn how to run off-chain infrastructure services, such as running a spy or a customized relayer. + /** + * @notice Add minter for the local domain. + * @dev Reverts if a minter is already set for the local domain. + * @param newLocalMinter The address of the minter on the local domain. + */ + function addLocalMinter(address newLocalMinter) external onlyOwner { + require(newLocalMinter != address(0), "Zero address not allowed"); -
+ require( + address(localMinter) == address(0), + "Local minter is already set." + ); -- :octicons-terminal-16:{ .lg .middle } **Relayers** + localMinter = ITokenMinter(newLocalMinter); - --- + emit LocalMinterAdded(newLocalMinter); + } - Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. + /** + * @notice Remove the minter for the local domain. + * @dev Reverts if the minter of the local domain is not set. + */ + function removeLocalMinter() external onlyOwner { + address _localMinterAddress = address(localMinter); + require(_localMinterAddress != address(0), "No local minter is set."); - [:custom-arrow: Run a relayer](/docs/infrastructure/relayers/run-relayer/) + delete localMinter; + emit LocalMinterRemoved(_localMinterAddress); + } -
+ // ============ Internal Utils ============ + /** + * @notice Deposits and burns tokens from sender to be minted on destination domain. + * Emits a `DepositForBurn` event. + * @param _amount amount of tokens to burn (must be non-zero) + * @param _destinationDomain destination domain + * @param _mintRecipient address of mint recipient on destination domain + * @param _burnToken address of contract to burn deposited tokens, on local domain + * @param _destinationCaller caller on the destination domain, as bytes32 + * @return nonce unique nonce reserved by message + */ + function _depositForBurn( + uint256 _amount, + uint32 _destinationDomain, + bytes32 _mintRecipient, + address _burnToken, + bytes32 _destinationCaller + ) internal returns (uint64 nonce) { + require(_amount > 0, "Amount must be nonzero"); + require(_mintRecipient != bytes32(0), "Mint recipient must be nonzero"); -
+ bytes32 _destinationTokenMessenger = _getRemoteTokenMessenger( + _destinationDomain + ); -- :octicons-terminal-16:{ .lg .middle } **Spy** + ITokenMinter _localMinter = _getLocalMinter(); + IMintBurnToken _mintBurnToken = IMintBurnToken(_burnToken); + require( + _mintBurnToken.transferFrom( + msg.sender, + address(_localMinter), + _amount + ), + "Transfer operation failed" + ); + _localMinter.burn(_burnToken, _amount); - --- + // Format message body + bytes memory _burnMessage = BurnMessage._formatMessage( + messageBodyVersion, + Message.addressToBytes32(_burnToken), + _mintRecipient, + _amount, + Message.addressToBytes32(msg.sender) + ); - Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. + uint64 _nonceReserved = _sendDepositForBurnMessage( + _destinationDomain, + _destinationTokenMessenger, + _destinationCaller, + _burnMessage + ); - [:custom-arrow: Run a Spy](/docs/infrastructure/spy/run-spy/) + emit DepositForBurn( + _nonceReserved, + _burnToken, + _amount, + msg.sender, + _mintRecipient, + _destinationDomain, + _destinationTokenMessenger, + _destinationCaller + ); -
---- END CONTENT --- + return _nonceReserved; + } -Doc-Content: https://wormhole.com/docs/build/infrastructure/relayers/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. -categories: Relayers ---- + /** + * @notice Sends a BurnMessage through the local message transmitter + * @dev calls local message transmitter's sendMessage() function if `_destinationCaller` == bytes32(0), + * or else calls sendMessageWithCaller(). + * @param _destinationDomain destination domain + * @param _destinationTokenMessenger address of registered TokenMessenger contract on destination domain, as bytes32 + * @param _destinationCaller caller on the destination domain, as bytes32. If `_destinationCaller` == bytes32(0), + * any address can call receiveMessage() on destination domain. + * @param _burnMessage formatted BurnMessage bytes (message body) + * @return nonce unique nonce reserved by message + */ + function _sendDepositForBurnMessage( + uint32 _destinationDomain, + bytes32 _destinationTokenMessenger, + bytes32 _destinationCaller, + bytes memory _burnMessage + ) internal returns (uint64 nonce) { + if (_destinationCaller == bytes32(0)) { + return + localMessageTransmitter.sendMessage( + _destinationDomain, + _destinationTokenMessenger, + _burnMessage + ); + } else { + return + localMessageTransmitter.sendMessageWithCaller( + _destinationDomain, + _destinationTokenMessenger, + _destinationCaller, + _burnMessage + ); + } + } -# Relayers + /** + * @notice Mints tokens to a recipient + * @param _tokenMinter address of TokenMinter contract + * @param _remoteDomain domain where burned tokens originate from + * @param _burnToken address of token burned + * @param _mintRecipient recipient address of minted tokens + * @param _amount amount of minted tokens + */ + function _mintAndWithdraw( + address _tokenMinter, + uint32 _remoteDomain, + bytes32 _burnToken, + address _mintRecipient, + uint256 _amount + ) internal { + ITokenMinter _minter = ITokenMinter(_tokenMinter); + address _mintToken = _minter.mint( + _remoteDomain, + _burnToken, + _mintRecipient, + _amount + ); -## Get Started + emit MintAndWithdraw(_mintRecipient, _amount, _mintToken); + } -
+ /** + * @notice return the remote TokenMessenger for the given `_domain` if one exists, else revert. + * @param _domain The domain for which to get the remote TokenMessenger + * @return _tokenMessenger The address of the TokenMessenger on `_domain` as bytes32 + */ + function _getRemoteTokenMessenger(uint32 _domain) + internal + view + returns (bytes32) + { + bytes32 _tokenMessenger = remoteTokenMessengers[_domain]; + require(_tokenMessenger != bytes32(0), "No TokenMessenger for domain"); + return _tokenMessenger; + } -- :octicons-terminal-16:{ .lg .middle } **Run a Custom Relayer** + /** + * @notice return the local minter address if it is set, else revert. + * @return local minter as ITokenMinter. + */ + function _getLocalMinter() internal view returns (ITokenMinter) { + require(address(localMinter) != address(0), "Local minter is not set"); + return localMinter; + } - --- + /** + * @notice Return true if the given remote domain and TokenMessenger is registered + * on this TokenMessenger. + * @param _domain The remote domain of the message. + * @param _tokenMessenger The address of the TokenMessenger on remote domain. + * @return true if a remote TokenMessenger is registered for `_domain` and `_tokenMessenger`, + * on this TokenMessenger. + */ + function _isRemoteTokenMessenger(uint32 _domain, bytes32 _tokenMessenger) + internal + view + returns (bool) + { + return + _tokenMessenger != bytes32(0) && + remoteTokenMessengers[_domain] == _tokenMessenger; + } - This section guides you through developing your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. + /** + * @notice Returns true if the message sender is the local registered MessageTransmitter + * @return true if message sender is the registered local message transmitter + */ + function _isLocalMessageTransmitter() internal view returns (bool) { + return + address(localMessageTransmitter) != address(0) && + msg.sender == address(localMessageTransmitter); + } +} + ``` -
+ This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMessenger.sol){target=\_blank} on GitHub. - Benefits of running your own relayer: +The functions provided by the Token Messenger contract are as follows: - - You can add logic to customize the delivery of messages - - You can perform off-chain computations resulting in optimized gas costs +- **`depositForBurn`** - deposits and burns tokens from the sender to be minted on the destination domain. Minted tokens will be transferred to `mintRecipient` -
+ ??? interface "Parameters" - Requirements for running your own relayer: + `amount` ++"uint256"++ + + The amount of tokens to burn. - - You are responsible for developing and hosting your relayer - - You are responsible for paying target chain fees - - You are responsible for the liveness of your relayer + --- -
+ `destinationDomain` ++"uint32"++ + + The network where the token will be minted after burn. - [:custom-arrow: Get started now](/docs/infrastructure/relayers/run-relayer/) + --- -
+ `mintRecipient` ++"bytes32"++ + + Address of mint recipient on destination domain. -## Additional Resources + --- -
+ `burnToken` ++"address"++ + + Address of contract to burn deposited tokens, on local domain. -- :octicons-question-16:{ .lg .middle } **What is a Relayer?** + ??? interface "Returns" - --- + `_nonce` ++"uint64"++ + + Unique nonce reserved by message. - Learn about what a relayer is, what role it plays in the delivery of cross-chain messages, and the different types of relayers in the Wormhole ecosystem. + ??? interface "Emits" - [:custom-arrow: Learn more about relayers](/docs/learn/infrastructure/relayer/) + `DepositForBurn` - event emitted when `depositForBurn` is called. The `destinationCaller` is set to `bytes32(0)` to allow any address to call `receiveMessage` on the destination domain -- :octicons-gear-16:{ .lg .middle } **Simplify the Development Process** + ??? child "Event Arguments" + + `nonce` ++"uint64"++ + + Unique nonce reserved by message (indexed). --- - Use the Wormhole Relayer Engine package as a foundational toolkit to develop your own customized off-chain relaying service, enabling tailored message handling. + `burnToken` ++"address"++ + + Address of token burnt on source domain. - [:custom-arrow: Check out the Relayer Engine source code](https://github.com/wormhole-foundation/relayer-engine){target=\_blank} + --- -
---- END CONTENT --- + `amount` ++"uint256"++ + + The deposit amount. -Doc-Content: https://wormhole.com/docs/build/infrastructure/relayers/run-relayer/ ---- BEGIN CONTENT --- ---- -title: Run a Relayer -description: Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -categories: Relayers ---- + --- -# Run a Custom Relayer + `depositor` ++"address"++ + + Address where deposit is transferred from. -## Introduction + --- -Relayers play a crucial role in cross-chain communication, ensuring that messages are transferred seamlessly between different blockchains. While Wormhole relayers provide a reliable way to handle these transfers, they might not always meet every application's unique requirements. + `mintRecipient` ++"bytes32"++ + + Address receiving minted tokens on destination domain. -Custom relayers address these limitations by offering tailored solutions that cater to the distinct needs of your application. Developing a custom relayer gives you complete control over message processing, delivery mechanisms, and integration with existing systems. This customization allows for optimized performance and the ability to implement specific features that Wormhole-deployed relayers might not support. + --- -A custom relayer might be as simple as an in-browser process that polls the API for the availability of a VAA after submitting a transaction and delivers it to the target chain. It might also be implemented with a Spy coupled with some daemon listening for VAAs from a relevant chain ID and emitter, then taking action when one is observed. + `destinationDomain` ++"uint32"++ - + + Destination domain. -This guide teaches you how to set up and configure a custom relayer for efficient message handling. You'll start by understanding how to uniquely identify a VAA using its emitter address, sequence ID, and chain ID. Then, you'll explore the Relayer Engine, a package that provides a framework for building custom relayers, and learn how to fetch and handle VAAs using the Wormhole SDK. + --- -## Get Started with a Custom Relayer + `destinationTokenMessenger` ++"bytes32"++ + + Address of `TokenMessenger` on destination domain. + + --- -To start building a custom relayer, it's essential to grasp the components you'll be managing as part of your relaying service. Your relayer must be capable of retrieving and delivering VAAs. + `destinationCaller` ++"bytes32"++ + + Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. -
- ![Custom relayer](/docs/images/build/infrastructure/relayers/run-relayer/relayer-1.webp) -
The off-chain components outlined in blue must be implemented.
-
+- **`depositForBurnWithCaller`** - deposits and burns tokens from the sender to be minted on the destination domain. This method differs from `depositForBurn` in that the mint on the destination domain can only be called by the designated `destinationCaller` address -### How to Uniquely Identify a VAA + ??? interface "Parameters" -Regardless of the environment, to get the VAA you intend to relay, you need: + `amount` ++"uint256"++ + + The amount of tokens to burn. -- The `emitter` address -- The `sequence` ID of the message you're interested in -- The `chainId` for the chain that emitted the message + --- -With these three components, you're able to uniquely identify a VAA and process it. + `destinationDomain` ++"uint32"++ + + The network where the token will be minted after burn. -## Use the Relayer Engine + --- -The [`relayer-engine`](https://github.com/wormhole-foundation/relayer-engine){target=\_blank} is a package that provides the structure and a starting point for a custom relayer. + `mintRecipient` ++"bytes32"++ + + Address of mint recipient on destination domain. -With the Relayer Engine, a developer can write specific logic for filtering to receive only the messages they care about. + --- -Once a Wormhole message is received, the developer may apply additional logic to parse custom payloads or submit the Verifiable Action Approvals (VAA) to one or many destination chains. + `burnToken` ++"address"++ + + Address of contract to burn deposited tokens, on local domain. -To use the Relayer Engine, a developer may specify how to relay Wormhole messages for their app using an idiomatic Express/Koa middleware-inspired API, then let the library handle all the details. + --- -### Install the Relayer Engine + `destinationCaller` ++"bytes32"++ + + Address of the caller on the destination domain who will trigger the mint. -First, install the `relayer-engine` package with your favorite package manager: + ??? interface "Returns" -```bash -npm i @wormhole-foundation/relayer-engine -``` + `_nonce` ++"uint64"++ + + Unique nonce reserved by message. -### Get Started with the Relayer Engine + ??? interface "Emits" -In the following example, you'll: + `DepositForBurn` - event emitted when `depositForBurnWithCaller` is called -1. Set up a `StandardRelayerApp`, passing configuration options for our relayer -2. Add a filter to capture only those messages our app cares about, with a callback to do _something_ with the VAA once received -3. Start the relayer app + ??? child "Event Arguments" -```typescript -import { - Environment, - StandardRelayerApp, - StandardRelayerContext, -} from '@wormhole-foundation/relayer-engine'; -import { CHAIN_ID_SOLANA } from '@certusone/wormhole-sdk'; + `nonce` ++"uint64"++ + + Unique nonce reserved by message (indexed). -(async function main() { - // Initialize relayer engine app and pass relevant config options - const app = new StandardRelayerApp( - Environment.TESTNET, - // Other app specific config options can be set here for things - // like retries, logger, or redis connection settings - { - name: 'ExampleRelayer', - } - ); + --- - // Add a filter with a callback that will be invoked - // on finding a VAA that matches the filter - app.chain(CHAIN_ID_SOLANA).address( - // Emitter address on Solana - 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe', - // Callback function to invoke on new message - async (ctx, next) => { - const vaa = ctx.vaa; - const hash = ctx.sourceTxHash; - console.log( - `Got a VAA with sequence: ${vaa.sequence} from with txhash: ${hash}` - ); - } - ); + `burnToken` ++"address"++ + + Address of token burnt on source domain. - // Add and configure any other middleware here + --- - // Start app. Blocks until unrecoverable error or process is stopped - await app.listen(); -})(); - -``` + `amount` ++"uint256"++ + + The deposit amount. -The first meaningful line instantiates the `StandardRelayerApp`, a subclass of the `RelayerApp` with standard defaults. + --- -```typescript -export class StandardRelayerApp< - ContextT extends StandardRelayerContext = StandardRelayerContext, -> extends RelayerApp { - // ... - constructor(env: Environment, opts: StandardRelayerAppOpts) { -``` + `depositor` ++"address"++ + + Address where deposit is transferred from. -The only field you pass in the `StandardRelayerAppOpts` is the name to help identify log messages and reserve a namespace in Redis. + --- -??? code "`StandardRelayerAppOpts`" + `mintRecipient` ++"bytes32"++ + + Address receiving minted tokens on destination domain. - Other options can be passed to the `StandardRelayerApp` constructor to configure the app further. + --- - ```typescript - wormholeRpcs?: string[]; // List of URLs from which to query missed VAAs -concurrency?: number; // How many concurrent requests to make for workflows -spyEndpoint?: string; // The hostname and port of our Spy -logger?: Logger; // A custom Logger -privateKeys?: Partial<{ [k in ChainId]: any[]; }>; // A set of keys that can be used to sign and send transactions -tokensByChain?: TokensByChain; // The token list we care about -workflows?: { retries: number; }; // How many times to retry a given workflow -providers?: ProvidersOpts; // Configuration for the default providers -fetchSourceTxhash?: boolean; // whether or not to get the original transaction ID/hash -// Redis config -redisClusterEndpoints?: ClusterNode[]; -redisCluster?: ClusterOptions; -redis?: RedisOptions; - ``` + `destinationDomain` ++"uint32"++ - + + Destination domain. -The next meaningful line in the example adds a filter middleware component. This middleware will cause the relayer app to request a subscription from the Spy for any VAAs that match the criteria and invoke the callback with the VAA. + --- -If you'd like your program to subscribe to `multiple` chains and addresses, you can call the same method several times or use the `multiple` helper. + `destinationTokenMessenger` ++"bytes32"++ + + Address of `TokenMessenger` on destination domain. + + --- -```typescript -app.multiple( - { - [CHAIN_ID_SOLANA]: 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe', - [CHAIN_ID_ETH]: ['0xabc1230000000...', '0xdef456000...'], - }, - myCallback -); -``` + `destinationCaller` ++"bytes32"++ + + Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. -The last line in the simple example runs `await app.listen()`, which starts the relayer engine. Once started, the Relayer Engine issues subscription requests to the Spy and begins any other workflows (e.g., tracking missed VAAs). +- **`replaceDepositForBurn`** — replaces a previous `BurnMessage` to modify the mint recipient and/or the destination caller. The replacement message reuses the `_nonce` created by the original message, which allows the original message's sender to update the details without requiring a new deposit -This will run until the process is killed or encounters an unrecoverable error. To gracefully shut down the relayer, call `app.stop()`. + ??? interface "Parameters" -The source code for this example is available in the [`relayer-engine` repository](https://github.com/wormhole-foundation/relayer-engine/blob/main/examples/simple/src/app.ts){target=\_blank}. + `originalMessage` ++"bytes"++ + + The original burn message to be replaced. -## Start Background Processes + --- -!!! note - These processes _must_ be running for the relayer app below to work. + `originalAttestation` ++"bytes"++ + + The attestation of the original message. -Next, you must start a Spy to listen for available VAAs published on the Guardian network. You also need a persistence layer. This example uses Redis. + --- -More details about the Spy are available in the [Spy Documentation](/docs/learn/infrastructure/spy){target=\_blank}. + `newDestinationCaller` ++"bytes32"++ + + The new caller on the destination domain, can be the same or updated. -### Wormhole Network Spy + --- -For our relayer app to receive messages, a local Spy must be running that watches the Guardian network. Our relayer app will receive updates from this Spy. + `newMintRecipient` ++"bytes32"++ + + The new recipient for the minted tokens, can be the same or updated. -=== "Mainnet Spy" + ??? interface "Returns" - ```bash - docker run --pull=always --platform=linux/amd64 \ - -p 7073:7073 \ - --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ - spy \ - --nodeKey /node.key \ - --spyRPC "[::]:7073" \ - --env mainnet - ``` + None. -=== "Testnet Spy" + ??? interface "Emits" - ```bash - docker run --pull=always --platform=linux/amd64 \ - -p 7073:7073 \ - --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ - spy \ - --nodeKey /node.key \ - --spyRPC "[::]:7073" \ - --env testnet - ``` + `DepositForBurn` - event emitted when `replaceDepositForBurn` is called. Note that the `destinationCaller` will reflect the new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (`bytes32(0)`), indicating that any destination caller is valid -### Redis Persistence + ??? child "Event Arguments" -!!! note - While you're using [Redis](https://redis.io/docs/latest/develop/get-started/){target=\_blank} here, the persistence layer can be swapped out for some other database by implementing the appropriate [interface](https://github.com/wormhole-foundation/relayer-engine/blob/main/relayer/storage/redis-storage.ts){target=\_blank}. + `nonce` ++"uint64"++ + + Unique nonce reserved by message (indexed). -A Redis instance must also be available to persist job data for fetching VAAs from the Spy. + --- -```bash -docker run --rm -p 6379:6379 --name redis-docker -d redis -``` + `burnToken` ++"address"++ + + Address of token burnt on source domain. -## Use the Wormhole SDK + --- -!!! note - The example below uses the legacy [`@certusone/wormhole-sdk`](https://www.npmjs.com/package/@certusone/wormhole-sdk){target=\_blank}, which is still supported and used in the Relayer Engine but is no longer actively maintained. + `amount` ++"uint256"++ - For most use cases, it is recommend to use the latest [`@wormhole-foundation/sdk`](https://www.npmjs.com/package/@wormhole-foundation/sdk){target=\_blank}. + The deposit amount. -You can also use the Wormhole SDK to poll the Guardian RPC until a signed VAA is ready using the SDK's `getSignedVAAWithRetry` function. + --- -```ts -import { - getSignedVAAWithRetry, - parseVAA, - CHAIN_ID_SOLANA, - CHAIN_ID_ETH, -} from '@certusone/wormhole-sdk'; + `depositor` ++"address"++ + + Address where deposit is transferred from. -const RPC_HOSTS = [ - /* ...*/ -]; + --- -async function getVAA( - emitter: string, - sequence: string, - chainId: number -): Promise { - // Wait for the VAA to be ready and fetch it from the guardian network - const { vaaBytes } = await getSignedVAAWithRetry( - RPC_HOSTS, - chainId, - emitter, - sequence - ); - return vaaBytes; -} + `mintRecipient` ++"bytes32"++ + + Address receiving minted tokens on destination domain. -const vaaBytes = await getVAA('INSERT_EMITTER_ADDRESS', 1, CHAIN_ID_ETH); - -``` + --- -Once you have the VAA, the delivery method is chain-dependent. + `destinationDomain` ++"uint32"++ - + + Destination domain. -=== "EVM" + --- - On EVM chains, the bytes for the VAA can be passed directly as an argument to an ABI method. + `destinationTokenMessenger` ++"bytes32"++ + + Address of `TokenMessenger` on destination domain. + + --- - ```ts - // Set up eth wallet -const ethProvider = new ethers.providers.StaticJsonRpcProvider( - 'INSERT_RPC_URL' -); -const ethWallet = new ethers.Wallet('INSERT_PRIVATE_KEY', ethProvider); + `destinationCaller` ++"bytes32"++ + + Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. -// Create client to interact with our target app -const ethHelloWorld = HelloWorld__factory.connect( - 'INSERT_CONTRACT_ADDRESS', - ethWallet -); +- **`handleReceiveMessage`** - handles an incoming message received by the local `MessageTransmitter` and takes the appropriate action. For a burn message, it mints the associated token to the requested recipient on the local domain. -// Invoke the receiveMessage on the ETH contract and wait for confirmation -const receipt = await ethHelloWorld - .receiveMessage(vaaBytes) - .then((tx: ethers.ContractTransaction) => tx.wait()) - .catch((msg: any) => { - console.error(msg); - return null; - }); - ``` + ???+ note -=== "Solana" + Though this function can only be called by the local `MessageTransmitter`, it is included here as it emits the essential event for minting tokens and withdrawing to send to the recipient. - On Solana, the VAA is first posted to the core bridge, and then a custom transaction is prepared to process and validate the VAA. + ??? interface "Parameters" - ```ts - import { CONTRACTS } from '@certusone/wormhole-sdk'; + `remoteDomain` ++"uint32"++ + + The domain where the message originated. -export const WORMHOLE_CONTRACTS = CONTRACTS[NETWORK]; -export const CORE_BRIDGE_PID = new PublicKey(WORMHOLE_CONTRACTS.solana.core); + --- -// First, post the VAA to the core bridge -await postVaaSolana( - connection, - wallet.signTransaction, - CORE_BRIDGE_PID, - wallet.key(), - vaaBytes -); + `sender` ++"bytes32"++ + + The address of the sender of the message. -const program = createHelloWorldProgramInterface(connection, programId); -const parsed = isBytes(wormholeMessage) - ? parseVaa(wormholeMessage) - : wormholeMessage; + --- -const ix = program.methods - .receiveMessage([...parsed.hash]) - .accounts({ - payer: new PublicKey(payer), - config: deriveConfigKey(programId), - wormholeProgram: new PublicKey(wormholeProgramId), - posted: derivePostedVaaKey(wormholeProgramId, parsed.hash), - foreignEmitter: deriveForeignEmitterKey(programId, parsed.emitterChain), - received: deriveReceivedKey( - programId, - parsed.emitterChain, - parsed.sequence - ), - }) - .instruction(); + `messageBody` ++"bytes"++ + + The bytes making up the body of the message. -const transaction = new Transaction().add(ix); -const { blockhash } = await connection.getLatestBlockhash(commitment); -transaction.recentBlockhash = blockhash; -transaction.feePayer = new PublicKey(payerAddress); + ??? interface "Returns" -const signed = await wallet.signTxn(transaction); -const txid = await connection.sendRawTransaction(signed); + `success` ++"boolean"++ + + Returns `true` if successful, otherwise, it returns `false`. -await connection.confirmTransaction(txid); - ``` ---- END CONTENT --- + ??? interface "Emits" -Doc-Content: https://wormhole.com/docs/build/infrastructure/spy/ ---- BEGIN CONTENT --- ---- -title: Spy -description: Discover everything you need to about the Wormhole Spy, a daemon that watches the Guardian Network and subscribe to signed messages. ---- + `MintAndWithdraw` - event emitted when tokens are minted -# Spy + ??? child "Event arguments" -## Get Started + `localMinter` ++"address"++ + + Minter responsible for minting and burning tokens on the local domain. -
+ --- -- :octicons-terminal-16:{ .lg .middle } **Run a Spy** + `remoteDomain` ++"uint32"++ + + The domain where the message originated from. - --- + --- - The content in this section shows you how you can run your own infrastructure and spin up a Spy daemon locally to subscribe to a stream of messages, also known as Verifiable Action Approvals (VAAs). + `burnToken` ++"address"++ + + Address of contract to burn deposited tokens, on local domain. - [:custom-arrow: Get started now](/docs/infrastructure/spy/run-spy/) + --- -
+ `mintRecipient` ++"address"++ + + Recipient address of minted tokens (indexed). -## Additional Resources + --- -
+ `amount` ++"uint256"++ + + Amount of minted tokens. -- :octicons-question-16:{ .lg .middle } **What is a Spy?** +### Message Transmitter Contract - --- +The Message Transmitter contract ensures secure messaging across blockchain domains by managing message dispatch and tracking communication with events like `MessageSent` and `MessageReceived`. It uses a unique nonce for each message, which ensures proper validation, verifies attestation signatures, and prevents replay attacks. - Learn about what a Spy is and what role it plays in the delivery of cross-chain messages. +The contract supports flexible delivery options, allowing messages to be sent to a specific `destinationCaller` or broadcast more generally. It also includes domain-specific configurations to manage communication between chains. - [:custom-arrow: Learn more about Spies](/docs/learn/infrastructure/spy/) +Additional features include replacing previously sent messages, setting maximum message body sizes, and verifying that messages are received only once per nonce to maintain network integrity. -- :octicons-code-16:{ .lg .middle } **Interact with a Spy** +??? code "Message Transmitter contract" + ```solidity + /* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity 0.7.6; - --- +import "@memview-sol/contracts/TypedMemView.sol"; +import "./interfaces/IMessageTransmitter.sol"; +import "./interfaces/IMessageHandler.sol"; +import "./messages/Message.sol"; +import "./roles/Pausable.sol"; +import "./roles/Rescuable.sol"; +import "./roles/Attestable.sol"; - Use the Wormhole Spy SDK to subscribe to the stream of signed messages. +/** + * @title MessageTransmitter + * @notice Contract responsible for sending and receiving messages across chains. + */ +contract MessageTransmitter is + IMessageTransmitter, + Pausable, + Rescuable, + Attestable +{ + // ============ Events ============ + /** + * @notice Emitted when a new message is dispatched + * @param message Raw bytes of message + */ + event MessageSent(bytes message); - [:custom-arrow: Use the Wormhole Spy SDK](https://github.com/wormhole-foundation/wormhole/blob/main/spydk/js/README.md){target=\_blank} + /** + * @notice Emitted when a new message is received + * @param caller Caller (msg.sender) on destination domain + * @param sourceDomain The source domain this message originated from + * @param nonce The nonce unique to this message + * @param sender The sender of this message + * @param messageBody message body bytes + */ + event MessageReceived( + address indexed caller, + uint32 sourceDomain, + uint64 indexed nonce, + bytes32 sender, + bytes messageBody + ); -- :octicons-bookmark-16:{ .lg .middle } **Alternative Implementations** + /** + * @notice Emitted when max message body size is updated + * @param newMaxMessageBodySize new maximum message body size, in bytes + */ + event MaxMessageBodySizeUpdated(uint256 newMaxMessageBodySize); - --- - - Check out Beacon, an alternative highly available version of the Wormhole Spy. - - [:custom-arrow: Use Pyth Beacon](https://github.com/pyth-network/beacon){target=\_blank} + // ============ Libraries ============ + using TypedMemView for bytes; + using TypedMemView for bytes29; + using Message for bytes29; -
---- END CONTENT --- + // ============ State Variables ============ + // Domain of chain on which the contract is deployed + uint32 public immutable localDomain; -Doc-Content: https://wormhole.com/docs/build/infrastructure/spy/run-spy/ ---- BEGIN CONTENT --- ---- -title: Run a Spy -description: Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. ---- + // Message Format version + uint32 public immutable version; -# Run a Spy + // Maximum size of message body, in bytes. + // This value is set by owner. + uint256 public maxMessageBodySize; -## Introduction + // Next available nonce from this source domain + uint64 public nextAvailableNonce; -The Spy is a lightweight component in the Wormhole infrastructure designed to listen for and forward messages (Verifiable Action Approvals (VAAs)) published on the Wormhole network. Running a Spy locally allows developers to subscribe to a filtered stream of these messages, facilitating the development of custom relayers or other integrations with Wormhole. + // Maps a bytes32 hash of (sourceDomain, nonce) -> uint256 (0 if unused, 1 if used) + mapping(bytes32 => uint256) public usedNonces; -For a more comprehensive understanding of the Spy and its role within the Wormhole ecosystem, refer to the [Spy Documentation](/docs/learn/infrastructure/spy/){target=\_blank}. + // ============ Constructor ============ + constructor( + uint32 _localDomain, + address _attester, + uint32 _maxMessageBodySize, + uint32 _version + ) Attestable(_attester) { + localDomain = _localDomain; + maxMessageBodySize = _maxMessageBodySize; + version = _version; + } -## How to Start a Spy + // ============ External Functions ============ + /** + * @notice Send the message to the destination domain and recipient + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination chain as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessage( + uint32 destinationDomain, + bytes32 recipient, + bytes calldata messageBody + ) external override whenNotPaused returns (uint64) { + bytes32 _emptyDestinationCaller = bytes32(0); + uint64 _nonce = _reserveAndIncrementNonce(); + bytes32 _messageSender = Message.addressToBytes32(msg.sender); -To start a Spy locally, run the following Docker command: + _sendMessage( + destinationDomain, + recipient, + _emptyDestinationCaller, + _messageSender, + _nonce, + messageBody + ); -=== "Mainnet" + return _nonce; + } - ```sh - docker run --pull=always --platform=linux/amd64 \ - -p 7073:7073 \ - --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ - spy \ - --nodeKey /node.key \ - --spyRPC "[::]:7073" \ - --env mainnet - ``` + /** + * @notice Replace a message with a new message body and/or destination caller. + * @dev The `originalAttestation` must be a valid attestation of `originalMessage`. + * Reverts if msg.sender does not match sender of original message, or if the source domain of the original message + * does not match this MessageTransmitter's local domain. + * @param originalMessage original message to replace + * @param originalAttestation attestation of `originalMessage` + * @param newMessageBody new message body of replaced message + * @param newDestinationCaller the new destination caller, which may be the + * same as the original destination caller, a new destination caller, or an empty + * destination caller (bytes32(0), indicating that any destination caller is valid.) + */ + function replaceMessage( + bytes calldata originalMessage, + bytes calldata originalAttestation, + bytes calldata newMessageBody, + bytes32 newDestinationCaller + ) external override whenNotPaused { + // Validate each signature in the attestation + _verifyAttestationSignatures(originalMessage, originalAttestation); -=== "Testnet" + bytes29 _originalMsg = originalMessage.ref(0); - ```sh - docker run --pull=always --platform=linux/amd64 \ - -p 7073:7073 \ - --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ - spy \ - --nodeKey /node.key \ - --spyRPC "[::]:7073" \ - --env testnet - ``` + // Validate message format + _originalMsg._validateMessageFormat(); -If you want to run the Spy built from source, change `ghcr.io/wormhole-foundation/guardiand:latest` to `guardian` after building the `guardian` image. + // Validate message sender + bytes32 _sender = _originalMsg._sender(); + require( + msg.sender == Message.bytes32ToAddress(_sender), + "Sender not permitted to use nonce" + ); -Optionally, add the following flags to skip any VAAs with invalid signatures: + // Validate source domain + uint32 _sourceDomain = _originalMsg._sourceDomain(); + require( + _sourceDomain == localDomain, + "Message not originally sent from this domain" + ); -=== "Mainnet" + uint32 _destinationDomain = _originalMsg._destinationDomain(); + bytes32 _recipient = _originalMsg._recipient(); + uint64 _nonce = _originalMsg._nonce(); - ```sh - --ethRPC https://eth.drpc.org - --ethContract 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B - ``` + _sendMessage( + _destinationDomain, + _recipient, + newDestinationCaller, + _sender, + _nonce, + newMessageBody + ); + } -=== "Testnet" + /** + * @notice Send the message to the destination domain and recipient, for a specified `destinationCaller` on the + * destination domain. + * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. + * WARNING: if the `destinationCaller` does not represent a valid address, then it will not be possible + * to broadcast the message on the destination domain. This is an advanced feature, and the standard + * sendMessage() should be preferred for use cases where a specific destination caller is not required. + * @param destinationDomain Domain of destination chain + * @param recipient Address of message recipient on destination domain as bytes32 + * @param destinationCaller caller on the destination domain, as bytes32 + * @param messageBody Raw bytes content of message + * @return nonce reserved by message + */ + function sendMessageWithCaller( + uint32 destinationDomain, + bytes32 recipient, + bytes32 destinationCaller, + bytes calldata messageBody + ) external override whenNotPaused returns (uint64) { + require( + destinationCaller != bytes32(0), + "Destination caller must be nonzero" + ); - ```sh - --ethRPC https://sepolia.drpc.org/ - --ethContract 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 - ``` + uint64 _nonce = _reserveAndIncrementNonce(); + bytes32 _messageSender = Message.addressToBytes32(msg.sender); -Optionally, add the following flags to prevent unbounded log growth: + _sendMessage( + destinationDomain, + recipient, + destinationCaller, + _messageSender, + _nonce, + messageBody + ); -```sh ---log-opt max-size=10m \ ---log-opt max-file=3 -``` + return _nonce; + } -## Subscribe to Filtered VAAs + /** + * @notice Receive a message. Messages with a given nonce + * can only be broadcast once for a (sourceDomain, destinationDomain) + * pair. The message body of a valid message is passed to the + * specified recipient for further processing. + * + * @dev Attestation format: + * A valid attestation is the concatenated 65-byte signature(s) of exactly + * `thresholdSignature` signatures, in increasing order of attester address. + * ***If the attester addresses recovered from signatures are not in + * increasing order, signature verification will fail.*** + * If incorrect number of signatures or duplicate signatures are supplied, + * signature verification will fail. + * + * Message format: + * Field Bytes Type Index + * version 4 uint32 0 + * sourceDomain 4 uint32 4 + * destinationDomain 4 uint32 8 + * nonce 8 uint64 12 + * sender 32 bytes32 20 + * recipient 32 bytes32 52 + * messageBody dynamic bytes 84 + * @param message Message bytes + * @param attestation Concatenated 65-byte signature(s) of `message`, in increasing order + * of the attester address recovered from signatures. + * @return success bool, true if successful + */ + function receiveMessage(bytes calldata message, bytes calldata attestation) + external + override + whenNotPaused + returns (bool success) + { + // Validate each signature in the attestation + _verifyAttestationSignatures(message, attestation); -Once running, a [gRPC](https://grpc.io/){target=\_blank} client (i.e., your program) can subscribe to a filtered stream of messages (VAAs). + bytes29 _msg = message.ref(0); -Use this [proto-spec file](https://github.com/wormhole-foundation/wormhole/blob/main/proto/spy/v1/spy.proto){target=\_blank} to generate a client for the gRPC service. + // Validate message format + _msg._validateMessageFormat(); -!!! note - If using JavaScript/TypeScript, the [Spydk](https://www.npmjs.com/package/@certusone/wormhole-spydk){target=\_blank} makes setting up a client easier. + // Validate domain + require( + _msg._destinationDomain() == localDomain, + "Invalid destination domain" + ); -## Data Persistence + // Validate destination caller + if (_msg._destinationCaller() != bytes32(0)) { + require( + _msg._destinationCaller() == + Message.addressToBytes32(msg.sender), + "Invalid caller for message" + ); + } -The Spy does not have a built-in persistence layer, so it is typically paired with something like Redis or an SQL database to record relevant messages. + // Validate version + require(_msg._version() == version, "Invalid message version"); -The persistence layer needs to implement the appropriate interface. For example, you can check out the [Redis interface](https://github.com/wormhole-foundation/relayer-engine/blob/main/relayer/storage/redis-storage.ts){target=\_blank} used by the Relayer Engine, a package that implements a client and persistence layer for messages received from a Spy subscription. ---- END CONTENT --- + // Validate nonce is available + uint32 _sourceDomain = _msg._sourceDomain(); + uint64 _nonce = _msg._nonce(); + bytes32 _sourceAndNonce = _hashSourceAndNonce(_sourceDomain, _nonce); + require(usedNonces[_sourceAndNonce] == 0, "Nonce already used"); + // Mark nonce used + usedNonces[_sourceAndNonce] = 1; -Doc-Content: https://wormhole.com/docs/build/multigov/deploy-to-evm/ ---- BEGIN CONTENT --- ---- -title: Deploy MultiGov on EVM Chains -description: Set up and deploy MultiGov to EVM locally with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. -categories: MultiGov ---- + // Handle receive message + bytes32 _sender = _msg._sender(); + bytes memory _messageBody = _msg._messageBody().clone(); + require( + IMessageHandler(Message.bytes32ToAddress(_msg._recipient())) + .handleReceiveMessage(_sourceDomain, _sender, _messageBody), + "handleReceiveMessage() failed" + ); -# Deploy MultiGov on EVM Chains + // Emit MessageReceived event + emit MessageReceived( + msg.sender, + _sourceDomain, + _nonce, + _sender, + _messageBody + ); + return true; + } -This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/build/multigov/){target=\_blank}. + /** + * @notice Sets the max message body size + * @dev This value should not be reduced without good reason, + * to avoid impacting users who rely on large messages. + * @param newMaxMessageBodySize new max message body size, in bytes + */ + function setMaxMessageBodySize(uint256 newMaxMessageBodySize) + external + onlyOwner + { + maxMessageBodySize = newMaxMessageBodySize; + emit MaxMessageBodySizeUpdated(maxMessageBodySize); + } -Once your project is approved through the intake process and you’ve collaborated with the Tally team to tailor MultiGov to your requirements, use this guide to configure, compile, and deploy the necessary smart contracts across your desired blockchain networks. This deployment will enable decentralized governance across your hub and spoke chains. + // ============ Internal Utils ============ + /** + * @notice Send the message to the destination domain and recipient. If `_destinationCaller` is not equal to bytes32(0), + * the message can only be received on the destination chain when called by `_destinationCaller`. + * @dev Format the message and emit `MessageSent` event with message information. + * @param _destinationDomain Domain of destination chain + * @param _recipient Address of message recipient on destination domain as bytes32 + * @param _destinationCaller caller on the destination domain, as bytes32 + * @param _sender message sender, as bytes32 + * @param _nonce nonce reserved for message + * @param _messageBody Raw bytes content of message + */ + function _sendMessage( + uint32 _destinationDomain, + bytes32 _recipient, + bytes32 _destinationCaller, + bytes32 _sender, + uint64 _nonce, + bytes calldata _messageBody + ) internal { + // Validate message body length + require( + _messageBody.length <= maxMessageBodySize, + "Message body exceeds max size" + ); -## Prerequisites + require(_recipient != bytes32(0), "Recipient must be nonzero"); -To interact with MultiGov, you'll need the following: + // serialize message + bytes memory _message = Message._formatMessage( + version, + localDomain, + _destinationDomain, + _nonce, + _sender, + _recipient, + _destinationCaller, + _messageBody + ); -- Install [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} -- Install [Git](https://git-scm.com/downloads){target=\_blank} -- Clone the repository: - ```bash - git clone https://github.com/wormhole-foundation/multigov - cd evm # for evm testing/deploying - ``` + // Emit MessageSent event + emit MessageSent(_message); + } -## Development Setup + /** + * @notice hashes `_source` and `_nonce`. + * @param _source Domain of chain where the transfer originated + * @param _nonce The unique identifier for the message from source to + destination + * @return hash of source and nonce + */ + function _hashSourceAndNonce(uint32 _source, uint64 _nonce) + internal + pure + returns (bytes32) + { + return keccak256(abi.encodePacked(_source, _nonce)); + } -For developers looking to set up a local MultiGov environment: + /** + * Reserve and increment next available nonce + * @return nonce reserved + */ + function _reserveAndIncrementNonce() internal returns (uint64) { + uint64 _nonceReserved = nextAvailableNonce; + nextAvailableNonce = nextAvailableNonce + 1; + return _nonceReserved; + } +} + ``` -1. Install dependencies: - ```bash - forge install - ``` + This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol){target=\_blank} on GitHub. -2. Set up environment variables: - ```bash - cp .env.example .env - ``` +The functions provided by the Message Transmitter contract are as follows: - Edit `.env` with your specific [configuration](#configuration){target=\_blank} +- **`receiveMessage`** — processes and validates an incoming message and its attestation. If valid, it triggers further action based on the message body -3. Compile contracts: - ```bash - forge build - ``` + ??? interface "Parameters" -4. Deploy contracts (example for Sepolia testnet): + `message` ++"bytes"++ + + The message to be processed, including details such as sender, recipient, and message body. - For hub chains: - ```bash - forge script script/DeployHubContractsSepolia.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast - ``` + --- - For spoke chains (e.g., Optimism Sepolia): - ```bash - forge script script/DeploySpokeContractsOptimismSepolia.s.sol --rpc-url $OPTIMISM_SEPOLIA_RPC_URL --broadcast - ``` + `attestation` ++"bytes"++ + + Concatenated 65-byte signature(s) that attest to the validity of the `message`. -## Configuration + ??? interface "Returns" -When deploying MultiGov, several key parameters need to be set. Here are the most important configuration points: + `success` ++"boolean"++ + + Returns `true` if successful, otherwise, returns `false`. -### Hub Governor Key Parameters + ??? interface "Emits" -- `initialVotingDelay` ++"uint256"++ - the delay measured in seconds before voting on a proposal begins. For example, `86400` is one day -- `initialProposalThreshold` ++"uint256"++ - the number of tokens needed to create a proposal -- `initialQuorum` ++"uint256"++ - the minimum number of votes needed for a proposal to be successful -- `initialVoteWeightWindow` ++"uint256"++ - a window where the minimum checkpointed voting weight is taken for a given address. The window ends at the vote start for a proposal and begins at the vote start minus the vote weight window. The voting window is measured in seconds, e.g., `86400` is one day + `MessageReceived` - event emitted when a new message is received - !!! note - This helps mitigate cross-chain double voting. + ??? child "Event arguments" -### Hub Proposal Extender Key Parameters + `caller` ++"address"++ + + Caller on destination domain. -- `extensionDuration` ++"uint256"++ - the amount of time, in seconds, for which target proposals will be extended. For example, `10800` is three hours -- `minimumExtensionDuration` ++"uint256"++ - lower time limit, in seconds, for extension duration. For example, `3600` is one hour + --- -### Spoke Vote Aggregator Key Parameters + `sourceDomain` ++"uint32"++ + + The source domain this message originated from. -- `initialVoteWindow` ++"uint256"++ - the moving window in seconds for vote weight checkpoints. These checkpoints are taken whenever an address that is delegating sends or receives tokens. For example, `86400` is one day + --- - !!! note - This is crucial for mitigating cross-chain double voting + `nonce` ++"uint64"++ + + Nonce unique to this message (indexed). -### Hub Evm Spoke Vote Aggregator Key Parameters + --- -- `maxQueryTimestampOffset` ++"uint256"++ - the max timestamp difference, in seconds, between the requested target time in the query and the current block time on the hub. For example, `1800` is 30 minutes + `sender` ++"bytes32"++ + + Sender of this message. -### Updateable Governance Parameters + --- -The following key parameters can be updated through governance proposals: + `messageBody` ++"bytes"++ + + The body of the message. -- `votingDelay` - delay before voting starts (in seconds) -- `votingPeriod` - duration of the voting period (in seconds) -- `proposalThreshold` - threshold for creating proposals (in tokens) -- `quorum` - number of votes required for quorum -- `extensionDuration` - the amount of time for which target proposals will be extended (in seconds) -- `voteWeightWindow` - window for vote weight checkpoints (in seconds) -- `maxQueryTimestampOffset` - max timestamp difference allowed between a query's target time and the hub's block time +- **`sendMessage`** — sends a message to the destination domain and recipient. It increments the `nonce`, assigns a unique `nonce` to the message, and emits a `MessageSent` event -These parameters can be queried using their respective getter functions on the applicable contract. + ??? interface "Parameters" -To update these parameters, a governance proposal must be created, voted on, and executed through the standard MultiGov process. ---- END CONTENT --- + `destinationDomain` ++"uint32"++ + + The target blockchain network where the message is to be sent. -Doc-Content: https://wormhole.com/docs/build/multigov/deploy-to-solana/ ---- BEGIN CONTENT --- ---- -title: MultiGov Deployment to Solana -description: Learn how to deploy the MultiGov Staking Program on Solana, including setup, funding, deployment, and configuration steps. -categories: MultiGov ---- + --- -# Deploy MultiGov on Solana + `recipient` ++"bytes32"++ + + The recipient's address on the destination domain. -This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/learn/governance/architecture/){target=\_blank}. + --- -Once your project setup is complete, follow this guide to configure, compile, and deploy the necessary Solana programs and supporting accounts. This deployment enables decentralized governance participation on Solana as a spoke chain within the MultiGov system. + `messageBody` ++"bytes"++ + + The raw bytes content of the message. -## Prerequisites + ??? interface "Returns" -To deploy MultiGov on Solana, ensure you have the following installed: + `nonce` ++"uint64"++ + + Nonce unique to this message. - - Install [Git](https://git-scm.com/downloads){target=\_blank} - - Install [Node.js](https://nodejs.org/){target=\_blank} **`v20.10.0`** - - Install [Solana CLI](https://docs.anza.xyz/cli/install/){target=\_blank} **`v1.18.20`** - - Install [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`v0.30.1`** - - Install [Rust](https://www.rust-lang.org/tools/install){target=\_blank} **`v1.80.1`** - - Install [Docker](https://www.docker.com/get-started/){target=\_blank} - - Clone the repository: - ```bash - git clone https://github.com/wormhole-foundation/multigov.git - cd multigov/solana/ - ``` + ??? interface "Emits" -## Build the Project + `MessageSent` - event emitted when a new message is dispatched -To create a verifiable build of the MultiGov Staking Program, run the following command: +??? child "Event arguments" -```bash -./scripts/build_verifiable_staking_program.sh -``` + `message` ++"bytes"++ + + The raw bytes of the message. -Once the build is complete, the compiled artifacts will be available in the `target` folder. +- **`sendMessageWithCaller`** — sends a message to the destination domain and recipient, requiring a specific caller to trigger the message on the target chain. It increments the `nonce`, assigns a unique `nonce` to the message, and emits a `MessageSent` event -## Set Up the Deployer Account + ??? interface "Parameters" -For a successful deployment, you need a funded deployer account on Solana. This account will store the program and execute deployment transactions. + `destinationDomain` ++"uint32"++ + + The target blockchain network where the message is to be sent. -In this section, you will create a new keypair, check the account balance, and ensure it has enough SOL tokens to cover deployment costs. If needed, you can fund the account using different methods before deploying. + --- -### Generate a New Keypair + `recipient` ++"bytes32"++ + + The recipient's address on the destination domain. -To create a new keypair and save it to a file, run the following command: + --- -```bash -solana-keygen new --outfile ./app/keypairs/deployer.json -``` + `destinationCaller` ++"bytes32"++ + + The caller on the destination domain. -### Check the Deployer Account Address + --- -To retrieve the public address of the newly created keypair, run the following command: + `messageBody` ++"bytes"++ + + The raw bytes content of the message. -```bash -solana address -k ./app/keypairs/deployer.json -``` + ??? interface "Returns" -### Check the Deployer Account Balance + `nonce` ++"uint64"++ + + Nonce unique to this message. -To verify the current balance of the deployer account, run the following command: + ??? interface "Emits" -```bash -solana balance -k ./app/keypairs/deployer.json -``` + `MessageSent` - event emitted when a new message is dispatched -!!! warning - When deploying the MultiGov Staking Program, the deployer account must have enough SOL to cover deployment costs and transaction fees. +??? child "Event arguments" - - 7.60219224 SOL for deployment costs - - 0.00542 SOL for transaction fees + `message` ++"bytes"++ + + The raw bytes of the message. -### Fund the Deployer Account +- **`replaceMessage`** — replaces an original message with a new message body and/or updates the destination caller. The replacement message reuses the `_nonce` created by the original message -If the account does not have enough SOL, use one of the following methods to add funds. + ??? interface "Parameters" - - **Transfer SOL from another account** - if you already have SOL in another account, transfer it using a wallet (Phantom, Solflare, etc.) or in the terminal + `originalMessage` ++"bytes"++ + + The original message to be replaced. - ```bash - solana transfer --from /path/to/funder.json - ``` + --- - - **Request an airdrop (devnet only)** - if deploying to devnet, you can request free SOL + `originalAttestation` ++"bytes"++ + + Attestation verifying the original message. - ```bash - solana airdrop 2 -k ./app/keypairs/deployer.json - ``` + --- - - **Use a Solana faucet (devnet only)** - you can use online faucets to receive 10 free SOL + `newMessageBody` ++"bytes"++ + + The new content for the replaced message. - - [Solana Faucet](https://faucet.solana.com/){target=\_blank} + --- -## Deploy the MultiGov Staking Program + `newDestinationCaller` ++"bytes32"++ + + The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (`bytes32(0)`), indicating that any destination caller is valid. -With the deployer account set up and funded, you can deploy the MultiGov Staking Program to the Solana blockchain. This step involves deploying the program, verifying the deployment, and ensuring the necessary storage and metadata are correctly configured. Once the IDL is initialized, the program will be ready for further setup and interaction. + ??? interface "Returns" -### Deploy the Program + None. -Deploy the MultiGov Staking Program using Anchor: + ??? interface "Emits" -```bash -anchor deploy --provider.cluster https://api.devnet.solana.com --provider.wallet ./app/keypairs/deployer.json -``` + `MessageSent` - event emitted when a new message is dispatched -### Verify the Deployment +??? child "Event arguments" -After deployment, check if the program is successfully deployed by running the following command: + `message` ++"bytes"++ + + The raw bytes of the message. -```bash -solana program show INSERT_PROGRAM_ID -``` +### Token Minter Contract -### Extend Program Storage +The Token Minter contract manages the minting and burning of tokens across different blockchain domains. It maintains a registry that links local tokens to their corresponding remote tokens, ensuring that tokens maintain a 1:1 exchange rate across domains. -If the deployed program requires additional storage space for updates or functionality, extend the program storage using the following command: +The contract restricts minting and burning functions to a designated Token Messenger, which ensures secure and reliable cross-chain operations. When tokens are burned on a remote domain, an equivalent amount is minted on the local domain for a specified recipient, and vice versa. -```bash -solana program extend INSERT_PROGRAM_ID 800000 -``` +To enhance control and flexibility, the contract includes mechanisms to pause operations, set burn limits, and update the Token Controller, which governs token minting permissions. Additionally, it provides functionality to add or remove the local Token Messenger and retrieve the local token address associated with a remote token. -### Initialize the IDL +??? code "Token Minter contract" + ```solidity + /* + * Copyright (c) 2022, Circle Internet Financial Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +pragma solidity 0.7.6; -To associate an IDL file with the deployed program, run the following command: +import "./interfaces/ITokenMinter.sol"; +import "./interfaces/IMintBurnToken.sol"; +import "./roles/Pausable.sol"; +import "./roles/Rescuable.sol"; +import "./roles/TokenController.sol"; +import "./TokenMessenger.sol"; -```bash -anchor idl init --provider.cluster https://api.devnet.solana.com --filepath ./target/idl/staking.json INSERT_PROGRAM_ID -``` +/** + * @title TokenMinter + * @notice Token Minter and Burner + * @dev Maintains registry of local mintable tokens and corresponding tokens on remote domains. + * This registry can be used by caller to determine which token on local domain to mint for a + * burned token on a remote domain, and vice versa. + * It is assumed that local and remote tokens are fungible at a constant 1:1 exchange rate. + */ +contract TokenMinter is ITokenMinter, TokenController, Pausable, Rescuable { + // ============ Events ============ + /** + * @notice Emitted when a local TokenMessenger is added + * @param localTokenMessenger address of local TokenMessenger + * @notice Emitted when a local TokenMessenger is added + */ + event LocalTokenMessengerAdded(address localTokenMessenger); -## Configure the Staking Program + /** + * @notice Emitted when a local TokenMessenger is removed + * @param localTokenMessenger address of local TokenMessenger + * @notice Emitted when a local TokenMessenger is removed + */ + event LocalTokenMessengerRemoved(address localTokenMessenger); -The final step after deploying the MultiGov Staking Program is configuring it for proper operation. This includes running a series of deployment scripts to initialize key components and set important governance parameters. These steps ensure that staking, governance, and cross-chain communication function as expected. + // ============ State Variables ============ + // Local TokenMessenger with permission to call mint and burn on this TokenMinter + address public localTokenMessenger; -### Run Deployment Scripts + // ============ Modifiers ============ + /** + * @notice Only accept messages from the registered message transmitter on local domain + */ + modifier onlyLocalTokenMessenger() { + require(_isLocalTokenMessenger(), "Caller not local TokenMessenger"); + _; + } -After deploying the program and initializing the IDL, execute the following scripts **in order** to set up the staking environment and necessary accounts. + // ============ Constructor ============ + /** + * @param _tokenController Token controller address + */ + constructor(address _tokenController) { + _setTokenController(_tokenController); + } -1. Initialize the MultiGov Staking Program with default settings: + // ============ External Functions ============ + /** + * @notice Mints `amount` of local tokens corresponding to the + * given (`sourceDomain`, `burnToken`) pair, to `to` address. + * @dev reverts if the (`sourceDomain`, `burnToken`) pair does not + * map to a nonzero local token address. This mapping can be queried using + * getLocalToken(). + * @param sourceDomain Source domain where `burnToken` was burned. + * @param burnToken Burned token address as bytes32. + * @param to Address to receive minted tokens, corresponding to `burnToken`, + * on this domain. + * @param amount Amount of tokens to mint. Must be less than or equal + * to the minterAllowance of this TokenMinter for given `_mintToken`. + * @return mintToken token minted. + */ + function mint( + uint32 sourceDomain, + bytes32 burnToken, + address to, + uint256 amount + ) + external + override + whenNotPaused + onlyLocalTokenMessenger + returns (address mintToken) + { + address _mintToken = _getLocalToken(sourceDomain, burnToken); + require(_mintToken != address(0), "Mint token not supported"); + IMintBurnToken _token = IMintBurnToken(_mintToken); - ```bash - npx ts-node app/deploy/01_init_staking.ts - ``` + require(_token.mint(to, amount), "Mint operation failed"); + return _mintToken; + } -2. Create an Account Lookup Table (ALT) to optimize transaction processing: + /** + * @notice Burn tokens owned by this TokenMinter. + * @param burnToken burnable token address. + * @param burnAmount amount of tokens to burn. Must be + * > 0, and <= maximum burn amount per message. + */ + function burn(address burnToken, uint256 burnAmount) + external + override + whenNotPaused + onlyLocalTokenMessenger + onlyWithinBurnLimit(burnToken, burnAmount) + { + IMintBurnToken _token = IMintBurnToken(burnToken); + _token.burn(burnAmount); + } - ```bash - npx ts-node app/deploy/02_create_account_lookup_table.ts - ``` + /** + * @notice Add TokenMessenger for the local domain. Only this TokenMessenger + * has permission to call mint() and burn() on this TokenMinter. + * @dev Reverts if a TokenMessenger is already set for the local domain. + * @param newLocalTokenMessenger The address of the new TokenMessenger on the local domain. + */ + function addLocalTokenMessenger(address newLocalTokenMessenger) + external + onlyOwner + { + require( + newLocalTokenMessenger != address(0), + "Invalid TokenMessenger address" + ); -3. Set up airlock accounts: + require( + localTokenMessenger == address(0), + "Local TokenMessenger already set" + ); - ```bash - npx ts-node app/deploy/03_create_airlock.ts - ``` + localTokenMessenger = newLocalTokenMessenger; -4. Deploy a metadata collector: + emit LocalTokenMessengerAdded(localTokenMessenger); + } - ```bash - npx ts-node app/deploy/04_create_spoke_metadata_collector.ts - ``` + /** + * @notice Remove the TokenMessenger for the local domain. + * @dev Reverts if the TokenMessenger of the local domain is not set. + */ + function removeLocalTokenMessenger() external onlyOwner { + address _localTokenMessengerBeforeRemoval = localTokenMessenger; + require( + _localTokenMessengerBeforeRemoval != address(0), + "No local TokenMessenger is set" + ); -5. Configure vote weight window lengths: + delete localTokenMessenger; + emit LocalTokenMessengerRemoved(_localTokenMessengerBeforeRemoval); + } - ```bash - npx ts-node app/deploy/05_initializeVoteWeightWindowLengths.ts - ``` + /** + * @notice Set tokenController to `newTokenController`, and + * emit `SetTokenController` event. + * @dev newTokenController must be nonzero. + * @param newTokenController address of new token controller + */ + function setTokenController(address newTokenController) + external + override + onlyOwner + { + _setTokenController(newTokenController); + } -6. Deploy the message executor for handling governance messages: + /** + * @notice Get the local token address associated with the given + * remote domain and token. + * @param remoteDomain Remote domain + * @param remoteToken Remote token + * @return local token address + */ + function getLocalToken(uint32 remoteDomain, bytes32 remoteToken) + external + view + override + returns (address) + { + return _getLocalToken(remoteDomain, remoteToken); + } - ```bash - npx ts-node app/deploy/06_create_message_executor.ts + // ============ Internal Utils ============ + /** + * @notice Returns true if the message sender is the registered local TokenMessenger + * @return True if the message sender is the registered local TokenMessenger + */ + function _isLocalTokenMessenger() internal view returns (bool) { + return + address(localTokenMessenger) != address(0) && + msg.sender == address(localTokenMessenger); + } +} ``` -### Set MultiGov Staking Program Key Parameters + This contract and the interfaces and contracts it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMinter.sol){target=\_blank} on GitHub. -When deploying MultiGov on Solana, several key parameters need to be set. Here are the most important configuration points: +Most of the methods of the Token Minter contract can be called only by the registered Token Messenger. However, there is one publicly accessible method, a public view function that allows anyone to query the local token associated with a remote domain and token. - - `maxCheckpointsAccountLimit` ++"u64"++ - the maximum number of checkpoints an account can have. For example, `654998` is used in production, while `15` might be used for testing - - `hubChainId` `u16` - the chain ID of the hub network where proposals are primarily managed. For example, `10002` for Sepolia testnet - - `hubProposalMetadata` ++"[u8; 20]"++ - an array of bytes representing the address of the Hub Proposal Metadata contract on Ethereum. This is used to identify proposals from the hub - - `voteWeightWindowLength` ++"u64"++ - specifies the length of the checkpoint window in seconds in which the minimum voting weight is taken. The window ends at the vote start for a proposal and begins at the vote start minus the vote weight window. The vote weight window helps solve problems such as manipulating votes in a chain - - `votingTokenMint` ++"Pubkey"++ - the mint address of the token used for voting - - `governanceAuthority` ++"Pubkey"++ - the account's public key with the authority to govern the staking system. The `governanceAuthority` should not be the default Pubkey, as this would indicate an uninitialized or incorrectly configured setup - - `vestingAdmin` ++"Pubkey"++ - the account's public key for managing vesting operations. The `vestingAdmin` should not be the default Pubkey, as this would indicate an uninitialized or incorrectly configured setup - - `hubDispatcher` ++"Pubkey"++ - the Solana public key derived from an Ethereum address on the hub chain that dispatches messages to the spoke chains. This is crucial for ensuring that only authorized messages from the hub are executed on the spoke ---- END CONTENT --- +- **`getLocalToken`** — a read-only function that returns the local token address associated with a given remote domain and token -Doc-Content: https://wormhole.com/docs/build/multigov/faq/ ---- BEGIN CONTENT --- ---- -title: MultiGov Technical FAQs -description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. -categories: MultiGov ---- + ??? interface "Parameters" -# FAQs + `remoteDomain` ++"uint32"++ + + The remote blockchain domain where the token resides. -## Technical Questions + --- -### How does MultiGov ensure security in cross-chain communication? + `remoteToken` ++"bytes32"++ + + The address of the token on the remote domain. -MultiGov leverages Wormhole's robust cross-chain communication protocol. It implements several security measures: + ??? interface "Returns" -- Message origin verification to prevent unauthorized governance actions -- Timely and consistent data checks to ensure vote aggregation is based on recent and synchronized chain states -- Authorized participant validation to maintain the integrity of the governance process -- Replay attack prevention by tracking executed messages + ++"address"++ + + The local token address. -### Can MultiGov integrate with any blockchain? +## How to Interact with CCTP Contracts -MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/build/start-building/supported-networks/). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole CCTP contracts. The primary functionality revolves around the following: -### How are votes aggregated across different chains? +- **Sending tokens with a message payload** - initiating a cross-chain transfer of Circle-supported assets along with a message payload to a specific target address on the target chain +- **Receiving tokens with a message payload** - validating messages received from other chains via Wormhole and then minting the tokens for the recipient -Votes are collected on each spoke chain using each chain's `SpokeVoteAggregator`. These votes are then transmitted to the HubVotePool on the hub chain for aggregation and tabulation. The `HubEvmSpokeVoteDecoder` standardizes votes from different EVM chains to ensure consistent processing. +### Sending Tokens and Messages -### Can governance upgrade from a single chain to MultiGov? +To initiate a cross-chain transfer, you must call the `transferTokensWithPayload` method of Wormhole's Circle Integration (CCTP) contract. Once you have initiated a transfer, you must fetch the attested Wormhole message and parse the transaction logs to locate a transfer message emitted by the Circle Bridge contract. Then, a request must be sent to Circle's off-chain process with the transfer message to grab the attestation from the process's response, which validates the token mint on the target chain. -Yes! MultiGov can support progressively upgrading from a single-chain governance to MultiGov. Moving to MultiGov requires upgrading the token to NTT and adding Flexible Voting to the original Governor. +To streamline this process, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/main){target=\_blank}, which exposes the [`WormholeRelayerSDK.sol` contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank}, including the [`CCTPSender` abstract contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase.sol){target=\_blank}. By inheriting this contract, you can transfer USDC while automatically relaying the message payload to the destination chain via a Wormhole-deployed relayer. -## Usage Questions +??? code "CCTP Sender contract" -### How can I create a proposal in MultiGov? + ```solidity + abstract contract CCTPSender is CCTPBase { + uint8 internal constant CONSISTENCY_LEVEL_FINALIZED = 15; -Proposals are created on the hub chain using the `HubEvmSpokeAggregateProposer` contract or by calling `propose` on the `HubGovernor`. You need to prepare the proposal details, including targets, values, and calldatas. The proposer's voting weight is aggregated across chains using Wormhole queries to determine eligibility. + using CCTPMessageLib for *; -### How do I vote on a proposal if I hold tokens on a spoke chain? + mapping(uint16 => uint32) public chainIdToCCTPDomain; -You can vote on proposals via the `SpokeVoteAggregator` contract on the respective spoke chain where you hold your tokens. The votes are then automatically forwarded to the hub chain for aggregation. + /** + * Sets the CCTP Domain corresponding to chain 'chain' to be 'cctpDomain' + * So that transfers of USDC to chain 'chain' use the target CCTP domain 'cctpDomain' + * + * This action can only be performed by 'cctpConfigurationOwner', who is set to be the deployer + * + * Currently, cctp domains are: + * Ethereum: Wormhole chain id 2, cctp domain 0 + * Avalanche: Wormhole chain id 6, cctp domain 1 + * Optimism: Wormhole chain id 24, cctp domain 2 + * Arbitrum: Wormhole chain id 23, cctp domain 3 + * Base: Wormhole chain id 30, cctp domain 6 + * + * These can be set via: + * setCCTPDomain(2, 0); + * setCCTPDomain(6, 1); + * setCCTPDomain(24, 2); + * setCCTPDomain(23, 3); + * setCCTPDomain(30, 6); + */ + function setCCTPDomain(uint16 chain, uint32 cctpDomain) public { + require( + msg.sender == cctpConfigurationOwner, + "Not allowed to set CCTP Domain" + ); + chainIdToCCTPDomain[chain] = cctpDomain; + } -### How are approved proposals executed across multiple chains? + function getCCTPDomain(uint16 chain) internal view returns (uint32) { + return chainIdToCCTPDomain[chain]; + } -When a proposal is approved and the timelock period elapses, it's first executed on the hub chain. A proposal can include a cross-chain message by including a call to `dispatch` on the `HubMessageDispatcher`, which sends a message to the relevant spoke chains. On each spoke chain, the `SpokeMessageExecutor` receives, verifies, and automatically executes the instructions using the `SpokeAirlock` as the `msg.sender`. + /** + * transferUSDC wraps common boilerplate for sending tokens to another chain using IWormholeRelayer + * - approves the Circle TokenMessenger contract to spend 'amount' of USDC + * - calls Circle's 'depositForBurnWithCaller' + * - returns key for inclusion in WormholeRelayer `additionalVaas` argument + * + * Note: this requires that only the targetAddress can redeem transfers. + * + */ -## Implementation Questions + function transferUSDC( + uint256 amount, + uint16 targetChain, + address targetAddress + ) internal returns (MessageKey memory) { + IERC20(USDC).approve(address(circleTokenMessenger), amount); + bytes32 targetAddressBytes32 = addressToBytes32CCTP(targetAddress); + uint64 nonce = circleTokenMessenger.depositForBurnWithCaller( + amount, + getCCTPDomain(targetChain), + targetAddressBytes32, + USDC, + targetAddressBytes32 + ); + return + MessageKey( + CCTPMessageLib.CCTP_KEY_TYPE, + abi.encodePacked(getCCTPDomain(wormhole.chainId()), nonce) + ); + } -### What are the requirements for using MultiGov? + // Publishes a CCTP transfer of 'amount' of USDC + // and requests a delivery of the transfer along with 'payload' to 'targetAddress' on 'targetChain' + // + // The second step is done by publishing a wormhole message representing a request + // to call 'receiveWormholeMessages' on the address 'targetAddress' on chain 'targetChain' + // with the payload 'abi.encode(amount, payload)' + // (and we encode the amount so it can be checked on the target chain) + function sendUSDCWithPayloadToEvm( + uint16 targetChain, + address targetAddress, + bytes memory payload, + uint256 receiverValue, + uint256 gasLimit, + uint256 amount + ) internal returns (uint64 sequence) { + MessageKey[] memory messageKeys = new MessageKey[](1); + messageKeys[0] = transferUSDC(amount, targetChain, targetAddress); -To use MultiGov, your DAO must meet the following requirements: + bytes memory userPayload = abi.encode(amount, payload); + address defaultDeliveryProvider = wormholeRelayer + .getDefaultDeliveryProvider(); -- **ERC20Votes token** - your DAO's token must implement the `ERC20Votes` standard and support `CLOCK_MODE` timestamps for compatibility with cross-chain governance -- **Flexible voting support** - your DAO's Governor must support Flexible Voting to function as the Hub Governor. If your existing Governor does not support Flexible Voting, you can upgrade it to enable this feature + (uint256 cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + receiverValue, + gasLimit + ); -### What do I need to set up MultiGov for my project? + sequence = wormholeRelayer.sendToEvm{value: cost}( + targetChain, + targetAddress, + userPayload, + receiverValue, + 0, + gasLimit, + targetChain, + address(0x0), + defaultDeliveryProvider, + messageKeys, + CONSISTENCY_LEVEL_FINALIZED + ); + } -Get started by filling out the form below: + function addressToBytes32CCTP(address addr) private pure returns (bytes32) { + return bytes32(uint256(uint160(addr))); + } +} + ``` -https://www.tally.xyz/get-started +The `CCTPSender` abstract contract exposes the `sendUSDCWithPayloadToEvm` function. This function publishes a CCTP transfer of the provided `amount` of USDC and requests that the transfer be delivered along with a `payload` to the specified `targetAddress` on the `targetChain`. -Tally will reach out to help get your DAO set up with MultiGov. +```solidity +function sendUSDCWithPayloadToEvm( + uint16 targetChain, + address targetAddress, + bytes memory payload, + uint256 receiverValue, + uint256 gasLimit, + uint256 amount +) internal returns (uint64 sequence) +``` -To set up testing MultiGov for your DAO, you'll need: +??? interface "Parameters" -- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} and [Git](https://git-scm.com/downloads){target=\_blank} installed -- Test ETH on the testnets you plan to use (e.g., Sepolia for hub, Optimism Sepolia for spoke) -- Modify and deploy the hub and spoke contracts using the provided scripts -- Set up the necessary environment variables and configurations + `targetChain` ++"uint16"++ -### Can MultiGov be used with non-EVM chains? + The target chain for the transfer. -The current implementation is designed for EVM-compatible chains. However, Solana (non-EVM) voting is currently in development and expected to go live after the EVM contracts. + --- -### How can I customize voting parameters in MultiGov? + `targetAddress` ++"address"++ -Voting parameters such as voting delay, voting period, proposal threshold, and quorum (and others) can be customized in the deployment scripts (`DeployHubContractsSepolia.s.sol` and `DeploySpokeContractsOptimismSepolia.s.sol` as examples for their respective chains). Make sure to adjust these parameters according to your DAO's specific needs before deployment. + The target address for the transfer. -Remember to thoroughly test your MultiGov implementation on testnets before deploying to Mainnet, and have your contracts audited for additional security. - -### How does MultiGov handle potential network issues or temporary chain unavailability? - -MultiGov includes several mechanisms to handle network issues or temporary chain unavailability: - -1. **Asynchronous vote aggregation** - votes are aggregated periodically, allowing the system to continue functioning even if one chain is temporarily unavailable -2. **Proposal extension** - the `HubGovernorProposalExtender` allows trusted actors to extend voting periods if needed, which can help mitigate issues caused by temporary network problems -3. **Wormhole retry mechanism** - Wormhole's infrastructure includes retry mechanisms for failed message deliveries, helping ensure cross-chain messages eventually get through -4. **Decentralized relayer network** - Wormhole's decentralized network of relayers helps maintain system availability even if some relayers are offline - -However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. ---- END CONTENT --- + --- -Doc-Content: https://wormhole.com/docs/build/multigov/ ---- BEGIN CONTENT --- ---- -title: Getting Started with MultiGov -description: Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. -categories: MultiGov ---- + `payload` ++"bytes"++ -# MultiGov + Arbitrary payload to be delivered to the target chain via Wormhole. -## Begin the MultiGov Integration Process + --- -Take the following steps to get started with a MultiGov integration: + `gasLimit` ++"uint256"++ -1. Evaluate if [MultiGov](/docs/learn/governance/) meets your cross-chain governance needs -2. Fill out the intake form on the [Tally website](https://www.tally.xyz/get-started){target=\_blank} -3. The Tally team will review your application and contact you to discuss implementation details -4. Work with the Tally team to customize and deploy MultiGov for your specific use case + The gas limit with which to call `targetAddress`. -## Start Building + --- -
+ `amount` ++"uint256"++ -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** + The amount of USDC to transfer. --- - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. +??? interface "Returns" - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) + `sequence` ++"uint64"++ -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** + Sequence number of the published VAA containing the delivery instructions. - --- +When the `sendUSDCWithPayloadToEvm` function is called, the following series of actions are executed: - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. +1. **USDC transfer initiation**: - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) + - The Circle Token Messenger contract is approved to spend the specified amount of USDC. + - The `depositForBurnWithCaller` function of the Token Messenger contract is invoked + - A key is returned, which is to be provided to the Wormhole relayer for message delivery -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on EVM Chains** +2. **Message encoding** - the message `payload` is encoded for transmission via the Wormhole relayer. The encoded value also includes the `amount` so that it can be checked on the target chain +3. **Retrieving delivery provider** - the current default delivery provider's address is retrieved +4. **Cost calculation** - the transfer cost is calculated using the Wormhole relayer's `quoteEVMDeliveryPrice` function +5. **Message dispatch**: - --- + - The `sendToEvm` function of the Wormhole relayer is called with the encoded payload, the delivery provider's address, and the arguments passed to `sendUSDCWithPayloadToEvm` + - The function must be called with `msg.value` set to the previously calculated cost (from step 4) + - This function publishes an instruction for the delivery provider to relay the payload and VAAs specified by the key (from step 1) to the target address on the target chain - Learn the process and key considerations for upgrading MultiGov contracts, ensuring system integrity and careful planning across cross-chain components. +A simple example implementation is as follows: - [:custom-arrow: Discover how to upgrade MultiGov on EVM Chains](/docs/build/multigov/upgrade-evm/) +```solidity +function sendCrossChainDeposit( + uint16 targetChain, + address targetAddress, + address recipient, + uint256 amount, + uint256, + gasLimit +) public payable { + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must be quoteCrossChainDeposit(targetChain)" + ); -- :octicons-file-code-16:{ .lg .middle } **Upgrade MultiGov on Solana** + IERC20(USDC).transferFrom(msg.sender, address(this), amount); - --- + bytes memory payload = abi.encode(recipient); + sendUSDCWithPayloadToEvm( + targetChain, + targetAddress, // address (on targetChain) to send token and payload to + payload, + 0, // receiver value + gasLimit, + amount + ); +} +``` - Learn how to upgrade the MultiGov Staking Program on Solana, including updating the program binary, IDL, and more. +The above example sends a specified amount of USDC and the recipient's address as a payload to a target contract on another chain, ensuring that the correct cost is provided for the cross-chain transfer. - [:custom-arrow: Discover how to upgrade MultiGov on Solana](/docs/build/multigov/upgrade-solana/) +### Receiving Tokens and Messages -- :octicons-question-16:{ .lg .middle } **Technical FAQs** +To complete the cross-chain transfer, you must invoke the `redeemTokensWithPayload` function on the target Wormhole Circle Integration contract. This function verifies the message's authenticity, decodes the payload, confirms the recipient and sender, checks message delivery, and then calls the `receiveMessage` function of the [Message Transmitter](#message-transmitter-contract) contract. - --- +Using the Wormhole-deployed relayer automatically triggers the `receiveWormholeMessages` function. This function is defined in the [`WormholeRelayerSDK.sol` contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank} from the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/main){target=\_blank} and is implemented within the [`CCTPReceiver` abstract contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase.sol){target=\_blank}. - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. +??? code "CCTP Receiver contract" - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) + ```solidity + abstract contract CCTPReceiver is CCTPBase { + function redeemUSDC( + bytes memory cctpMessage + ) internal returns (uint256 amount) { + (bytes memory message, bytes memory signature) = abi.decode( + cctpMessage, + (bytes, bytes) + ); + uint256 beforeBalance = IERC20(USDC).balanceOf(address(this)); + circleMessageTransmitter.receiveMessage(message, signature); + return IERC20(USDC).balanceOf(address(this)) - beforeBalance; + } -
+ function receiveWormholeMessages( + bytes memory payload, + bytes[] memory additionalMessages, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 deliveryHash + ) external payable { + // Currently, 'sendUSDCWithPayloadToEVM' only sends one CCTP transfer + // That can be modified if the integrator desires to send multiple CCTP transfers + // in which case the following code would have to be modified to support + // redeeming these multiple transfers and checking that their 'amount's are accurate + require( + additionalMessages.length <= 1, + "CCTP: At most one Message is supported" + ); -## Additional Resources + uint256 amountUSDCReceived; + if (additionalMessages.length == 1) + amountUSDCReceived = redeemUSDC(additionalMessages[0]); -
+ (uint256 amount, bytes memory userPayload) = abi.decode( + payload, + (uint256, bytes) + ); -- :octicons-book-16:{ .lg .middle } **What is MultiGov?** + // Check that the correct amount was received + // It is important to verify that the 'USDC' sent in by the relayer is the same amount + // that the sender sent in on the source chain + require(amount == amountUSDCReceived, "Wrong amount received"); - --- + receivePayloadAndUSDC( + userPayload, + amountUSDCReceived, + sourceAddress, + sourceChain, + deliveryHash + ); + } + + // Implement this function to handle in-bound deliveries that include a CCTP transfer + function receivePayloadAndUSDC( + bytes memory payload, + uint256 amountUSDCReceived, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 deliveryHash + ) internal virtual {} +} + ``` - Need to familiarize yourself with MultiGov? Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. +Although you do not need to interact with the `receiveWormholeMessages` function directly, it's important to understand what it does. This function processes cross-chain messages and USDC transfers via Wormhole's Circle (CCTP) Bridge. Here's a summary of what it does: - [:custom-arrow: Learn the basics](/docs/learn/governance/) +1. **Validate additional messages** - the function checks that there is at most one CCTP transfer message in the `additionalMessages` array, as it currently only supports processing a single CCTP transfer +2. **Redeem USDC**: + - If there is a CCTP message, it calls the `redeemUSDC` function of the `CCTPReceiver` contract to decode and redeem the USDC + - This results in the call of the `receiveMessage` function of Circle's Message Transmitter contract to redeem the USDC based on the provided message and signature + - The amount of USDC received is calculated by subtracting the contract's previous balance from the current balance after redeeming the USDC +3. **Decode payload** - the incoming payload is decoded, extracting both the expected amount of USDC and a `userPayload` (which could be any additional data) +4. **Verify the amount** - it ensures that the amount of USDC received matches the amount encoded in the payload. If the amounts don't match, the transaction is reverted +5. **Handle the payload and USDC** - after verifying the amounts, `receivePayloadAndUSDC` is called, which is meant to handle the actual logic for processing the received payload and USDC transfer -- :octicons-checklist-16:{ .lg .middle } **Tutorials** +You'll need to implement the `receivePayloadAndUSDC` function to transfer the USDC and handle the payload as your application needs. A simple example implementation is as follows: - --- +```solidity +function receivePayloadAndUSDC( + bytes memory payload, + uint256 amountUSDCReceived, + bytes32, // sourceAddress + uint16, // sourceChain + bytes32 // deliveryHash +) internal override onlyWormholeRelayer { + address recipient = abi.decode(payload, (address)); - Access step-by-step tutorials for executing cross-chain governance actions, including treasury management proposals with MultiGov. + IERC20(USDC).transfer(recipient, amountUSDCReceived); +} +``` - [:custom-arrow: Learn by building](/docs/tutorials/multigov/) +## Complete Example -
+To view a complete example of creating a contract that integrates with Wormhole's CCTP contracts to send and receive USDC cross-chain, check out the [Hello USDC](https://github.com/wormhole-foundation/hello-usdc){target=\_blank} repository on GitHub. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/upgrade-evm/ +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/overview/ --- BEGIN CONTENT --- --- -title: Upgrading MultiGov on EVM -description: Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. -categories: MultiGov +title: CCTP Bridge with Wormhole +description: Learn how the integration of Circle's CCTP with Wormhole enables secure and efficient native USDC transfers and complex cross-chain interactions. +categories: Transfer --- -# Upgrade MultiGov Contracts on EVM Chains +# CCTP with Wormhole Overview -MultiGov is designed to be flexible but stable. Due to the system's complexity and cross-chain nature, upgrades should be rare and carefully considered. When upgrades are necessary, they must be meticulously planned and executed to ensure system integrity and continuity. +The integration of [Circle's Cross-Chain Transfer Protocol (CCTP)](https://www.circle.com/cross-chain-transfer-protocol){target=\_blank} with the Wormhole messaging protocol creates a robust system for securely and efficiently transferring native USDC across different blockchain networks while enabling more complex multichain interactions. This combination streamlines the movement of stablecoins, reduces risk, and unlocks new possibilities for decentralized applications. -## Key Considerations for Upgrades +## Key Features -- **`HubGovernor`**: - - Not upgradeable. A new deployment requires redeploying several components of the MultiGov system. Refer to the [Process for Major System Upgrade](#process-for-major-system-upgrade) section for more details +- **Secure native USDC transfers**: At its core, CCTP provides a "burn-and-mint" mechanism for transferring native USDC. This eliminates the need for wrapped assets and the associated risks of intermediary bridges. +- **Atomic execution**: By combining CCTP and Wormhole, the transfer of USDC and the execution of accompanying instructions on the destination chain can occur as a single atomic transaction. +- **Automated relaying**: Eliminates the need for users to redeem USDC transfers themselves. +- **Enhanced composability**: Developers can build more sophisticated cross-chain applications by sending additional data alongside the transfer. +- **Gas drop off**: Enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer. +- **Gas payment**: Covering destination gas in automated vs. manual transfers. + - **Automated**: Users often don't need destination gas tokens upfront, relayers cover these gas costs, reimbursed via gas drop-off or initial fees. + - **Manual**: Users pay destination gas directly, the protocol may offer post-claim USDC-to-gas conversion. -- **`HubVotePool`**: - - Can be replaced by setting a new `HubVotePool` on the `HubGovernor` - - Requires re-registering all spokes on the new `HubVotePool` - - Must register the query type and implementation for vote decoding by calling `registerQueryType` on the new `HubVotePool` - - A new proposal would have to authorize the governor to use the newly created hub vote pool and will also handle registering the appropriate query decoders and registering the appropriate spoke `SpokeVoteAggregators` +## How It Works -- **`SpokeMessageExecutor`**: - - Upgradeable via [UUPS](https://www.rareskills.io/post/uups-proxy){target=\_blank} proxy pattern - - Stores critical parameters in `SpokeMessageExecutorStorage` +This section outlines the end-to-end flow for transferring native USDC across chains using CCTP while optionally triggering an action on the destination chain. Circle and Wormhole coordinate each step to ensure a secure, verifiable transfer and execution process. -- **`HubEvmSpokeAggregateProposer`**: - - Needs redeployment if `HubGovernor` changes - - Requires re-registering all spokes after redeployment +1. **Alice initiates a transfer on Ethereum**: She submits a request to the Circle Bridge to send 100 USDC to Avalanche. If desired, she could include optional payload data. -- **`HubProposalMetadata`**: - - Needs redeployment if `HubGovernor` changes, as it references `HubGovernor` as a parameter +2. **Tokens are taken into custody and burned**: The Circle Bridge takes custody of Alice's USDC and initiates a burn using Circle's CCTP, triggering an off-chain attestation process. -- **`SpokeMetadataCollector`**: - - Requires redeployment if the hub chain ID changes or if `HubProposalMetadata` changes +3. **A Wormhole message is published**: The transfer metadata is emitted as a Wormhole message. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate and sign it to produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. -## Process for Major System Upgrade +4. **A relayer automatically processes the messages**: Once the VAA and Circle attestation are available, a relayer submits them to the Circle Bridge on Avalanche. -1. **New `HubGovernor` deployment**: - - Deploy the new `HubGovernor` contract -1. **Component redeployment**: - - Redeploy `HubEvmSpokeAggregateProposer` with the new `HubGovernor` address - - Redeploy `HubProposalMetadata` referencing the new `HubGovernor` - - If hub chain ID changes, redeploy `SpokeMetadataCollector` on all spoke chains -1. **`HubVotePool` update**: - - Set the new `HubVotePool` on the new `HubGovernor` - - Register all spokes on the new `HubVotePool` - - Register the query type and implementation for vote decoding (`HubEvmSpokeVoteDecoder`) -1. **Spoke re-registration**: - - Re-register all spokes on the new `HubEvmSpokeAggregateProposer` -1. **Verification and testing**: - - Conduct thorough testing of the new system setup - - Verify all cross-chain interactions are functioning correctly -1. **System transition and deprecation**: - - Create a proposal to switch the timelock to the new governor - - Communicate clearly to the community what changes were made -1. **Monitoring**: - - Implement a transition period where the new system is closely monitored - - Address any issues that arise promptly +5. **Tokens are minted**: The Circle Bridge verifies both proofs and mints 100 USDC to Alice using Circle's CCTP. If a payload is included, it can be executed atomically. -## Important Considerations +```mermaid +sequenceDiagram + participant User as Alice + participant SourceChain as Circle Bridge
on Ethereum + participant Circle + participant Guardians as Wormhole Guardians + participant Relayer + participant DestinationChain as Circle Bridge
on Avalanche -- Always prioritize system stability, upgrades should only be performed when absolutely necessary -- Thoroughly audit all new contract implementations before proposing an upgrade -- Account for all affected components across all chains in the upgrade plan -- Provide comprehensive documentation for the community about the upgrade process and any changes in functionality -- Always test upgrades extensively on testnets before implementing in production + User->>SourceChain: Submit transfer
(100 USDC to Avalanche) + SourceChain->>Circle: Initiate a burn + Circle->>Circle: Burn USDC and provide attestation + SourceChain->>Guardians: Emit Wormhole message (transfer metadata) + Guardians->>Guardians: Sign message and produce VAA + Relayer->>Guardians: Fetch signed VAA + Relayer->>Circle: Fetch Circle burn attestation + Relayer->>DestinationChain: Submit VAA and
attestation + DestinationChain->>Circle: Verify Circle attestation + Circle->>User: Mint USDC to Alice +``` + +!!! note + For a cross-chain transfer to be successful, both the source and destination chains must be among those supported by [Circle's CCTP](https://developers.circle.com/stablecoins/supported-domains){target=\_blank}. + +## Use Cases + +Integrating Wormhole's messaging with CCTP enables the secure transfer of native USDC across blockchains, unlocking key cross-chain use cases, which include: + +- **USDC Payments Across Chains** + - [**CCTP**](/docs/products/cctp-bridge/get-started/): Transfer native USDC using Circle’s burn-and-mint protocol. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Automate attestation delivery and gas handling. + - [**Connect**](/docs/products/connect/overview/): Embed multichain USDC transfers directly in your app. + +- **USDC-Powered Multichain Settlement** + - [**Settlement**](/docs/products/settlement/overview/): Use the Liquidity Layer to settle intents with native USDC. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Initiate transfers, discover routes, and execute swaps seamlessly. + +## Next Steps + +Now that you're familiar with CCTP, here is a list of resources for more hands-on practice: + +- [**Get started with CCTP Bridge**](/docs/products/cctp-bridge/get-started/): Perform a multichain USDC transfer from Avalanche to Sepolia using Wormhole's TypeScript SDK and Circle's CCTP. +- [**Complete USDC Transfer Flow**](/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/): Execute a USDC cross-chain transfer using Wormhole SDK and Circle's CCTP, covering manual, automatic, and partial transfer recovery. +- [**Checkout Circle's CCTP Docs**](https://developers.circle.com/stablecoins/cctp-getting-started){target=\_blank}: Learn more about Circle's cross-chain transfer protocol in their documentation. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/multigov/upgrade-solana/ +Doc-Content: https://wormhole.com/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/ --- BEGIN CONTENT --- --- -title: Upgrading MultiGov on Solana -description: Learn the process and key considerations for upgrading MultiGov on Solana, ensuring system integrity and careful planning across cross-chain components. -categories: MultiGov +title: Complete USDC Transfer Flow +description: Learn how to perform USDC cross-chain transfers using Wormhole SDK and Circle's CCTP. Supports manual, automatic, and partial transfer recovery. --- -# Upgrade MultiGov Contracts on Solana +# Complete USDC Transfer Flow -The MultiGov Staking Program on Solana is designed to be upgradeable while maintaining stability. Upgrades introduce improvements, bug fixes, and new features but must be carefully planned and executed to prevent disruptions. +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-cctp-transfer){target=\_blank} -This guide covers the key considerations and step-by-step process for upgrading the MultiGov Staking Program, including updating the program binary, Interface Description Language (IDL), and `HubProposalMetadata` while ensuring cross-chain compatibility. +## Introduction -## Key Considerations for Upgrades +In this guide, we will show you how to bridge native USDC across different blockchain networks using [Circle's Cross-Chain Transfer Protocol](/docs/products/cctp-bridge/overview/){target=\_blank} (CCTP) and [Wormhole’s TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main){target=\_blank}. -- **Program upgradeability** - you can upgrade the MultiGov Staking Program on Solana using the `anchor upgrade` command - - You need the program's new bytecode (`.so` file) and an updated IDL file to reflect any changes in the program's interface to complete an upgrade - - The program's authority (deployer) must execute the upgrade +Traditionally, cross-chain transfers using CCTP involve multiple manual steps, such as initiating the transfer on the source chain, relaying messages between chains, and covering gas fees on both the source and destination chains. Without the TypeScript SDK, developers must handle these operations independently, adding complexity and increasing the chance for errors, mainly when dealing with gas payments on the destination chain and native gas token management. -- **`HubProposalMetadata`** - can be updated without redeploying the entire program. You can do this by invoking the `updateHubProposalMetadata` instruction - - You must carefully validate updates to `HubProposalMetadata` to ensure compatibility with the existing system +Wormhole’s TypeScript SDK simplifies this process by offering automated transfer relaying and handling gas payments on the destination chain. It also offers an option to include native gas tokens for seamless execution. This reduces developer overhead, makes transfers faster and more reliable, and enhances the user experience. -- **Cross-chain compatibility** - ensure any changes to the Solana program do not break compatibility with the Ethereum-based `HubGovernor` - - Test upgrades thoroughly on devnet before deploying to mainnet +In this guide, we’ll first explore the theory behind CCTP and then provide a step-by-step tutorial for integrating Wormhole’s TypeScript SDK into your application to streamline USDC transfers across multiple chains. -## Upgrade the MultiGov Program +## Core Concepts -Follow these steps to upgrade the MultiGov Staking Program on Solana: +When bridging assets across chains, there are two primary approaches to handling the transfer process: manual and automated. Below, you may find the differences between these approaches and how they impact the user experience: -1. **Prepare the new program binary** - build the updated program using the provided script + - **Manual transfers** - manual transfers involve three key steps: initiating the transfer on the source chain, fetching the Circle attestation to verify the transfer, and completing the transfer on the destination chain - ```bash - ./scripts/build_verifiable_staking_program.sh - ``` + - **Automated transfers** - automatic transfers simplify the process by handling Circle attestations and finalization for you. With Wormhole's automated relaying, you only need to initiate the transfer, and the rest is managed for you - The new program binary will be located at: +## Prerequisites - ```bash - target/deploy/staking.so - ``` +Before you begin, ensure you have the following: -2. **Upgrade the program** - use the anchor upgrade command to deploy the new program binary + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine + - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally + - [USDC tokens](https://faucet.circle.com/){target=\_blank} on supported chains. This tutorial uses Avalanche and Sepolia as examples + - A wallet with a private key, funded with native tokens (Testnet or Mainnet) for gas fees - ```bash - anchor upgrade --program-id INSERT_PROGRAM_ID --provider.cluster INSERT_CLUSTER_URL INSERT_PATH_TO_PROGRAM_BINARY - ``` +## Supported Chains + +The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains in the Wormhole SDK [GitHub repository](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/5810ebbd3635aaf1b5ab675da3f99f62aec2210f/core/base/src/constants/circle.ts#L14-L30){target=_blank}, which covers both Testnet and Mainnet environments. + +## Project Setup + +In this section, you'll set up your project for transferring USDC across chains using Wormhole's SDK and Circle's CCTP. We’ll guide you through initializing the project, installing dependencies, and preparing your environment for cross-chain transfers. + +1. **Initialize the project** - start by creating a new directory for your project and initializing it with `npm`, which will create the `package.json` file for your project - Your completed anchor upgrade command should resemble the following: ```bash - anchor upgrade --program-id DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY --provider.cluster https://api.devnet.solana.com ./target/deploy/staking.so + mkdir cctp-circle + cd cctp-circle + npm init -y ``` -3. **Update the IDL** - after upgrading the program, update the IDL to reflect any changes in the program's interface +2. **Create a `.gitignore` file** - ensure your private key isn't accidentally exposed or committed to version control ```bash - anchor idl upgrade INSERT_PROGRAM_ID --filepath INSERT_PATH_TO_IDL_FILE + echo ".env" >> .gitignore ``` - Your completed IDL upgrade command should resemble the following: +3. **Install dependencies** - install the required dependencies, including the Wormhole SDK and helper libraries + ```bash - anchor idl upgrade --provider.cluster https://api.devnet.solana.com --filepath ./target/idl/staking.json DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY + npm install @wormhole-foundation/sdk dotenv ``` -4. **Update `HubProposalMetadata`** - if `HubProposalMetadata` requires an update, run the following script to invoke the `updateHubProposalMetadata` instruction and apply the changes +4. **Set up environment variables** - to securely store your private key, create a `.env` file in the root of your project ```bash - npx ts-node app/deploy/07_update_HubProposalMetadata.ts + touch .env ``` ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/queries/faqs/ ---- BEGIN CONTENT --- ---- -title: Queries FAQs -description: Wormhole Queries FAQ covering available libraries, query examples, response formats, and details about running query proxy servers. -categories: Queries ---- -# Wormhole Queries FAQs + Inside the `.env` file, add your private key -## What libraries are available to handle queries? + ```env + ETH_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" + SOL_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" + ``` - - The [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} can be used to create query requests, mock query responses for testing, and parse query responses. The SDK also includes utilities for posting query responses + !!! note + Ensure your private key contains USDC funds and native tokens for gas on both the source and destination chains. -- The [Solidity `QueryResponseLib` library](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/QueryResponse.sol){target=\_blank} can be used to parse and verify query responses on EVM chains. See the [Solana Stake Pool](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} repository as an example use case +5. **Create a `helpers.ts` file** - to simplify the interaction between chains, create a file to store utility functions for fetching your private key, setting up signers for different chains, and managing transaction relays -- [`QueryRequestBuilder.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/testing/QueryRequestBuilder.sol){target=\_blank} can be used for mocking query requests and responses in Forge tests + 1. Create the helpers file -- The [Go query package](https://github.com/wormhole-foundation/wormhole/tree/main/node/pkg/query){target=\_blank} can also be used to create query requests and parse query responses + ```bash + mkdir helpers + touch helpers/helpers.ts + ``` -!!! note - A Rust SDK for Solana is being actively investigated by the Wormhole contributors. See the [Solana Queries Verification](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} repository as a proof of concept. + 2. Open the `helpers.ts` file and add the following code -## Are there any query examples? + ```typescript + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { config } from 'dotenv'; +config(); -Certainly. You can find a complete guide on the [Use Queries page](/docs/build/queries/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: +export interface SignerStuff { + chain: ChainContext; + signer: Signer; + address: ChainAddress; +} -- [Basic Example Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} -- [Solana Stake Pool Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} -- [Solana Program Derived Address (PDA) / Token Account Balance Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-pda){target=\_blank} -- [Solana Queries Verification Example](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} +// Function to fetch environment variables (like your private key) +function getEnv(key: string): string { + const val = process.env[key]; + if (!val) throw new Error(`Missing environment variable: ${key}`); + return val; +} -## What is the format of the response signature? +// Signer setup function for different blockchain platforms +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; -The Guardian node calculates an ECDSA signature using [`Sign` function of the crypto package](https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.21/crypto#Sign){target=\_blank} where the digest hash is: + switch (platform) { + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), getEnv('SOL_PRIVATE_KEY')); + break; + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), getEnv('ETH_PRIVATE_KEY')); + break; + default: + throw new Error('Unsupported platform: ' + platform); + } -```keccak256("query_response_0000000000000000000|"+keccak256(responseBytes))``` + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` -See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_key.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. + - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file + - **`getSigner`** - based on the chain you're working with (EVM, Solana, etc.), this function retrieves a signer for that specific platform. The signer is responsible for signing transactions and interacting with the blockchain. It securely uses the private key stored in your `.env` file -!!! note - If you are used to `ecrecover` you will notice that the `v` byte is `0` or `1` as opposed to `27` or `28`. The `signaturesToEvmStruct` method in the [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} accounts for this as well as structuring the signatures into an `IWormhole.SignatureStruct[]`. +6. **Create the main script** - create a new file named `manual-transfer.ts` to hold your script for transferring USDC across chains -## Can anyone run a query proxy server? + 1. Create the `manual-transfer.ts` file in the `src` directory -Permissions for Query Proxy are managed by the Guardians. The Guardian nodes are configured to only listen to a set of allow-listed proxies. However, it is possible that this restriction may be lifted in the future and/or more proxies could be added. + ```bash + touch src/manual-transfer.ts + ``` -It is also important to note that the proxies don't impact the verifiability of the request or result, i.e., their role in the process is trustless. + 2. Open the `manual-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files -## What Does Queries Offer over an RPC Service + ```typescript + import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { getSigner } from './helpers/helpers'; + ``` -Wormhole Queries provides on-demand, attested, on-chain, verifiable RPC results. Each Guardian independently executes the specified query and returns the result and their signature. The proxy handles aggregating the results and signatures, giving you a single result (all within one REST call) with a quorum of signatures suitable for on-chain submission, parsing, and verification using one of our examples or SDKs. ---- END CONTENT --- + - **`evm`** - this import is for working with EVM-compatible chains, like Avalanche, Ethereum, Base Sepolia, and more + - **`solana`** - this adds support for Solana, a non-EVM chain + - **`getSigner`** - utility function from the helper file that retrieves the signer to sign transactions -Doc-Content: https://wormhole.com/docs/build/queries/ ---- BEGIN CONTENT --- ---- -title: Wormhole Queries -description: Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. -categories: Queries ---- +## Manual Transfers -# Queries +In a manual USDC transfer, you perform each step of the cross-chain transfer process individually. This approach allows for greater control and flexibility over how the transfer is executed, which can be helpful in scenarios where you need to customize certain aspects of the transfer, such as gas management, specific chain selection, or signing transactions manually. -## Get Started +This section will guide you through performing a manual USDC transfer across chains using the Wormhole SDK and Circle’s CCTP. -Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. +### Set Up the Transfer Environment -
+#### Configure Transfer Details -- :octicons-book-16:{ .lg .middle } **Overview** +Before initiating a cross-chain transfer, you must set up the chain context and signers for both the source and destination chains. - --- +1. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM and Solana) to support. This allows us to interact with both EVM-compatible chains like Avalanche and non-EVM chains like Solana if needed - Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST API endpoint, enabling secure cross-chain interactions and verifications. + ```typescript + const wh = await wormhole('Testnet', [evm, solana]); + ``` + + !!! note + You can replace `'Testnet'` with `'Mainnet'` if you want to perform transfers on Mainnet. - [:custom-arrow: Learn about Queries](/docs/build/queries/overview/) +2. **Set up source and destination chains** - specify the source chain (Avalanche) and the destination chain (Sepolia) using the `getChain` method. This allows us to define where to send the USDC and where to receive them -- :octicons-code-16:{ .lg .middle } **Use Queries** + ```typescript + const rcvChain = wh.getChain('Sepolia'); + ``` - --- +3. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains - Explore a simple demo of interacting with Wormhole Queries using an `eth_call` request to query the supply of wETH on Ethereum using a Wormhole query. + ```typescript + const destination = await getSigner(rcvChain); + ``` - [:custom-arrow: Get hands-on](/docs/build/queries/use-queries/) +4. **Define the transfer amount** - the amount of USDC to transfer is specified. In this case, we're transferring 0.1 USDC, which is parsed and converted into the base units expected by the Wormhole SDK -- :octicons-book-16:{ .lg .middle } **Query FAQs** + ```typescript + + ``` - --- +5. **Set transfer mode** - we specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself - Explore frequently asked questions about Wormhole Queries. + ```typescript + + ``` - [:custom-arrow: Check out the FAQs](/docs/build/queries/faqs/) +#### Initiate the Transfer -
---- END CONTENT --- +To begin the manual transfer process, you first need to create the transfer object and then manually initiate the transfer on the source chain. -Doc-Content: https://wormhole.com/docs/build/queries/overview/ ---- BEGIN CONTENT --- ---- -title: Queries Overview -description: Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST endpoint, enabling secure cross-chain interactions and verifications. -categories: Queries ---- +1. **Create the Circle transfer object** - the `wh.circleTransfer()` function creates an object with the transfer details, such as the amount of USDC, the source and destination addresses, and the mode. However, this does not initiate the transfer itself -# Queries Overview {: #queries-overview } + ```typescript + amt, + source.address, + destination.address, + automatic + ); + ``` -Wormhole Guardians, who run full nodes for various connected chains, facilitate a new cross-chain query service that allows for on-demand attested responses to queries, bypassing the inefficiencies of traditional transaction-based data retrieval. This method is faster and cost-effective, eliminating the need for gas payments and transaction finality wait times. +2. **Start the transfer** - the `initiateTransfer` function sends the transaction on the source chain. It involves signing and sending the transaction using the source signer. This will return a list of transaction IDs (`srcTxIds`) that you can use to track the transfer -!!! note - Queries are currently in closed beta, though you can start developing today. Check out [Use Queries](/docs/build/queries/use-queries/){target=\_blank} and reach out to [Join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. + ```typescript + console.log(`Started Transfer: `, srcTxids); + ``` -Wormhole Queries offers on-demand access to Guardian-attested on-chain data. The current implementation provides integrators with a simple REST endpoint to initiate an off-chain request via a proxy. The proxy then forwards the request to the Guardians and gathers a quorum of responses. The result returns the encoded response, including the request details and the Guardian signatures. The request validation performed by the query module includes a three step process that involves verifying the signature to ensure it has the correct prefix, confirming that the signer is authorized to execute query requests, and validating the legitimacy of all per-chain requests contained in the query. You can read more about Queries in the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank}. +#### Fetch the Circle Attestation (VAA) -## The Flow of a Query {: #the-flow-of-a-query} +Once you initialize the transfer on the source chain, you must fetch the VAA from Circle. The VAA serves as cryptographic proof that CCTP has successfully recognized the transfer. The transfer cannot be completed on the destination chain until this attestation is fetched. -The general overview of a query's flow is as follows: an off-chain process sends HTTPS query requests to a Query Proxy, which validates and forwards them to the Guardians; these Guardians independently validate, sign, and return the response, with the entire process typically taking less than a second. -![The architecture flow of a query](/docs/images/build/queries/overview/overview-1.webp) +1. **Set a timeout** - fetching the attestation can take some time, so setting a timeout is common. In this example, we set the timeout to 60 seconds -The step-by-step flow of a query is as follows: + ```typescript + + ``` -1. An off-chain process initiates a query request via HTTPS to the query proxy (or Query Server) -2. The query proxy validates the request and forwards it to the Guardians via a gossip network -3. The Guardians independently validate the request, make the requisite RPC calls, verify the results, sign, and gossip a response back to the Query Proxy -4. The Query Proxy aggregates the results and returns a response when it reaches a quorum of two-thirds or more of the current Guardian set - the exact quorum requirements as the core bridge -5. The off-chain process can then submit these requests to an on-chain contract which should verify the signatures and validate the request before processing the result +2. **Fetch the attestation** - after initiating the transfer, you can use the `fetchAttestation()` function to retrieve the VAA. This function will wait until the attestation is available or you reach the specified timeout -In this flow, the Query Proxy is a permissioned but trustless part of the protocol. In most cases, this entire process takes less than one second. If a request is invalid or cannot be processed by the Guardians, they will retry for up to one minute before timing out. Requests can be batched to have the Guardians make multiple calls to multiple networks. This can further reduce overhead for processing query responses on-chain. Up to 255 queries can be batched together, with certain types allowing for batching themselves. + ```typescript + console.log(`Got Attestation: `, attestIds); + ``` -## Supported Query Types {: #supported-query-types} + The `attestIds` will contain the details of the fetched attestation, which Wormhole uses to complete the transfer on the destination chain -There are currently five supported types of queries. See [the white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md){target=\_blank} for more details on each. +#### Complete the Transfer on the Destination Chain -### eth_call {: #eth-call} +Once you fetch the VAA correctly, the final step is to complete the transfer on the destination chain (Sepolia in this example). This involves redeeming the VAA, which moves the USDC from Circle's custody onto the destination chain. -This query type is effectively an equivalent of [eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a block specified by number or hash. +Use the `completeTransfer()` function to finalize the transfer on the destination chain. This requires the destination signer to sign and submit the transaction to the destination chain -Calls are batched to allow specifying multiple calls (even to multiple contracts) against the same block. These calls are included in a single batch RPC call, simplifying on-chain verification. Up to 255 calls may be batched in an single `eth_call` query. +```typescript +console.log(`Completed Transfer: `, dstTxids); -The result contains the specified block number, hash, timestamp, and the call result. + console.log('Circle Transfer status: ', xfer); -### eth_call By Timestamp {: #eth-call-by-timestamp} + process.exit(0); +``` -This query type is similar to `eth_call` but targets a timestamp instead of a specific `block_id`. This can be useful when forming requests based on uncorrelated data, such as requiring data from another chain based on the block timestamp of a given chain. +The `dstTxIds` will hold the transaction IDs for the transfer on the destination chain, confirming that the transfer has been completed -The result also contains the target and block details with the following enforced conditions: `target_block.timestamp <= target_time < following_block.timestamp` and `following_block_num - 1 == target_block_num`. +You can find the full code for the manual USDC transfer script below: -### eth_call With Finality {: #eth-call-with-finality} +???- code "`manual-transfer.ts`" + ```typescript + import { wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { getSigner } from './helpers/helpers'; -This query type is similar to `eth_call` but ensures that the specified block has reached the specified finality before returning the query results. The finality may be `finalized` or `safe.` Note that if a chain doesn't natively support the `safe` tag, this will be equivalent to `finalized.` +(async function () { + const wh = await wormhole('Testnet', [evm, solana]); -### sol_account {: #sol_account} + // Set up source and destination chains + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Sepolia'); -This query is used to read data for one or more accounts on Solana, akin to [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank}. + // Configure the signers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -### sol_pda {: #sol_pda} - -This query is used to read data for one or more [Program Derived Addresses(PDA)](https://www.anchor-lang.com/docs/pdas){target=\_blank} on Solana, akin to calling [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} on the result of `PublicKey.findProgramAddressSync(seeds, programId).` This query is helpful for times when you want to more generally read accounts owned by a program and verify the derivation on another chain, like how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. - -## Supported Chains {: #supported-chains} + // Define the transfer amount (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) + const amt = 100_000n; -The following table provides expected support based on testing. However, the success of any given query is based on the success of the underlying call on each Guardian’s RPC node. + const automatic = false; -For example, many chains have implementations forked from [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which keeps 128 blocks of state in memory by default (without running in archive mode). While this is good for about 25 minutes of history on Ethereum Mainnet, it is only about three minutes on Optimism. While Guardian nodes can be expected to have access to recent state, there are currently no guarantees of how far back in history they have access to. + // Create the Circle transfer object + const xfer = await wh.circleTransfer( + amt, + source.address, + destination.address, + automatic + ); -### Mainnet {: #mainnet} + console.log('Circle Transfer object created:', xfer); -| Chain | Wormhole Chain ID | eth_call | By Timestamp | With Finality | Expected History | -|:-------------:|:-----------------:|:--------:|:------------------:|:-------------:|:----------------:| -| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | -| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | -| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | -| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | -| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | -| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | -| Karura | 11 | ✅ | ✅ | ✅ | archive | -| Acala | 12 | ✅ | ✅ | ✅ | archive | -| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | -| Celo | 14 | ✅ | ℹ️ hints required\* | ✅ | 128 blocks | -| Moonbeam | 16 | ✅ | ℹ️ hints required\* | ✅ | 256 blocks | -| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | -| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | -| Base | 30 | ✅ | ✅ | ✅ | archive | + // Initiate the transfer on the source chain (Avalanche) + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); -\*`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. + // Wait for Circle Attestation (VAA) + const timeout = 60 * 1000; // Timeout in milliseconds (60 seconds) + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(timeout); + console.log(`Got Attestation: `, attestIds); -## Next Steps {: #next-steps} + // Complete the transfer on the destination chain (Sepolia) + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, dstTxids); -Remember that Wormhole Queries are currently in beta. You can [register to join the beta](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to fully experiment with Wormhole Queries. + console.log('Circle Transfer status: ', xfer); -Be sure to check out the [FAQs](/docs/build/queries/faqs/){target=\_blank} and the [Use Queries guide](/docs/build/queries/use-queries/){target=\_blank}. + process.exit(0); +})(); + ``` -You can also check out the following examples of applications that make use of Wormhole Queries: +### Run Manual Transfer -- [Basic demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} -- [Solana Stake Pool](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} -- [Solana Program Derived Address (PDA) / Token Account Balance](https://github.com/wormholelabs-xyz/example-queries-solana-pda){target=\_blank} -- [Solana Queries Verification](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} ---- END CONTENT --- +To execute the manual transfer script, you can use `ts-node` to run the TypeScript file directly -Doc-Content: https://wormhole.com/docs/build/queries/use-queries/ ---- BEGIN CONTENT --- ---- -title: Use Queries -description: Explore a simple demo of interacting with Wormhole Queries using an eth_call request to query the supply of wETH on Ethereum using a Wormhole query. -categories: Queries ---- +```bash +npx ts-node src/manual-transfer.ts +``` -# Use Queries +This will initiate the USDC transfer from the source chain (Avalanche) and complete it on the destination chain (Sepolia). -You can visit the [Example Queries Demo](https://wormholelabs-xyz.github.io/example-queries-demo/){target=\_blank} to view an interactive example of an application interacting with the [Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/blob/main/src/QueryDemo.sol){target=\_blank} contract. +You can monitor the status of the transaction on the [Wormhole explorer](https://wormholescan.io/){target=\_blank}. -This guide covers using a simple `eth_call` request to get the total supply of WETH on Ethereum. +### Complete Partial Transfer -## RPC Basics +In some cases, a manual transfer might start but not finish—perhaps the user terminates their session, or there's an issue before the transfer can be completed. The Wormhole SDK allows you to reconstitute the transfer object from the transaction hash on the source chain. -Before digging into anything Queries-specific, this page will look at how to make an [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a public Ethereum RPC. Suppose you'd like to query the WETH contract for its total supply; before making a request, you need some information about the contract you want to call, including: +This feature is handy for recovering an incomplete transfer or when debugging. -- **To** - the contract to call. WETH is [0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2){target=\_blank} -- **Data** - the method identifier and ABI-encoded parameters, which can be obtained as follows: `web3.eth.abi.encodeFunctionSignature("totalSupply()")` which yields `0x18160ddd` -- **Block ID** - the block number, hash, or tag. Tag options include `latest,` `safe,` or `finalized` +Here’s how you can complete a partial transfer using just the source chain and transaction hash: -The prepared curl request is as follows: +```typescript +wh, + { + chain: 'Avalanche', + txid: '0x6b6d5f101a32aa6d2f7bf0bf14d72bfbf76a640e1b2fdbbeeac5b82069cda4dd', + }, + timeout + ); -```bash title="eth_call JSON-RPC request" -curl https://ethereum.publicnode.com -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","data":"0x18160ddd"},"latest"],"id":1}' + const dstTxIds = await xfer.completeTransfer(destination.signer); + console.log('Completed transfer: ', dstTxIds); ``` -And the corresponding response is: +You will need to provide the below requirements to complete the partial transfer: -```bash title="eth_call JSON-RPC reponse" -{ - "jsonrpc":"2.0", - "id":1, - "result":"0x000000000000000000000000000000000000000000029fd3d129b582d7949e71" -} -``` +- **Transaction ID (`txId`)** - the transaction hash from the source chain where the transfer was initiated +- **Signer for the destination chain (`destination.signer`)** - the wallet or private key that can authorize and complete the transfer on the destination chain. This signer is the same as the `destination.signer` defined in the manual transfer setup -Converting the returned value of the executed call from hexidecimal results in the value `3172615244782286193073777`. You can compare your result to the [**Read Contract**](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#readContract){target=\_blank} tab in Etherscan. Your result will be different as WETH is minted/burned over time. +This allows you to resume the transfer process by rebuilding the transfer object and completing it on the destination chain. It's especially convenient when debugging or handling interrupted transfers. -## Construct a Query {: #construct-a-query} +You can find the full code for the manual USDC transfer script below: -You can use the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} to construct a query. You will also need an RPC endpoint from the provider of your choice. This example uses [Axios](https://www.npmjs.com/package/axios){target=\_blank} for RPC requests. Ensure that you also have [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed. +??? code "`partial-transfer.ts`" + ```typescript + import { CircleTransfer, wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { getSigner } from '../helpers/helpers'; -```jsx -npm i @wormhole-foundation/wormhole-query-sdk axios -``` +(async function () { + // Initialize the Wormhole object for the Testnet environment and add supported chains (evm and solana) + const wh = await wormhole('Testnet', [evm, solana]); -In order to make an `EthCallQueryRequest`, you need a specific block number or hash as well as the call data to request. + // Grab chain Contexts -- these hold a reference to a cached rpc client + const rcvChain = wh.getChain('Sepolia'); -You can request the latest block from a public node using `eth_getBlockByNumber`. + // Get signer from local key + const destination = await getSigner(rcvChain); -```jsx + const timeout = 60 * 1000; // Timeout in milliseconds (60 seconds) -await axios.post(rpc, { - method: 'eth_getBlockByNumber', - params: ['latest', false], - id: 1, - jsonrpc: '2.0', - }) - ).data?.result?.number; -``` + // Rebuild the transfer from the source txid + const xfer = await CircleTransfer.from( + wh, + { + chain: 'Avalanche', + txid: '0x6b6d5f101a32aa6d2f7bf0bf14d72bfbf76a640e1b2fdbbeeac5b82069cda4dd', + }, + timeout + ); -Then construct the call data. + const dstTxIds = await xfer.completeTransfer(destination.signer); + console.log('Completed transfer: ', dstTxIds); -```jsx -to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH - data: '0x18160ddd', // web3.eth.abi.encodeFunctionSignature("totalSupply()") -}; -``` + console.log('Circle Transfer status: ', xfer); -Finally, put it all together in a `QueryRequest`. + process.exit(0); +})(); + ``` -```jsx -const request = new QueryRequest( - 0, // Nonce - [ - new PerChainQueryRequest( - 2, // Ethereum Wormhole Chain ID - new EthCallQueryRequest(latestBlock, [callData]) - ), - ] - ); -``` +## Automatic Transfers -This request consists of one `PerChainQueryRequest`, which is an `EthCallQueryRequest` to Ethereum. You can use `console.log` to print the JSON object and review the structure. +The automatic transfer process simplifies the steps by automating the attestation fetching and transfer completion. All you need to do is initiate the transfer. -```jsx +### Set Up the Transfer Environment -// { -// "nonce": 0, -// "requests": [ -// { -// "chainId": 2, -// "query": { -// "callData": [ -// { -// "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", -// "data": "0x18160ddd" -// } -// ], -// "blockTag": "0x11e9068" -// } -// } -// ], -// "version": 1 -// } -``` +#### Configure Transfer Details -## Mock a Query +The setup for automatic transfers is similar to manual transfers, with the key difference being that the `automatic` flag is `true`. This indicates that Wormhole will handle the attestation and finalization steps for you -For easier testing, the Query SDK provides a `QueryProxyMock` method. This method will perform the request and sign the result with the [Devnet](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} Guardian key. The `mock` call returns the same format as the Query Proxy. +```typescript -```jsx -const mockData = await mock.mock(request); - console.log(mockData); -// { -// signatures: ['...'], -// bytes: '...' -// } ``` -This response is suited for on-chain use, but the SDK also includes a parser to make the results readable via the client. +#### Initiate the Transfer -```jsx -const mockQueryResult = ( - mockQueryResponse.responses[0].response as EthCallQueryResponse - ).results[0]; - console.log( - `Mock Query Result: ${mockQueryResult} (${BigInt(mockQueryResult)})` +The transfer process is the same as that for manual transfers. You create the transfer object and then start the transfer on the source chain + +```typescript +amt, + source.address, + destination.address, + automatic ); -// Mock Query Result: 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee (3172556167631284394053614) ``` -Testing this all together might look like the following: +#### Log Transfer Details -```jsx -import { - EthCallData, - EthCallQueryRequest, - EthCallQueryResponse, - PerChainQueryRequest, - QueryProxyMock, - QueryRequest, - QueryResponse, -} from '@wormhole-foundation/wormhole-query-sdk'; -import axios from 'axios'; +After initiating the transfer, you can log the transaction IDs for both the source and destination chains. This will help you track the progress of the transfer -const rpc = 'https://ethereum.publicnode.com'; -const callData: EthCallData = { - to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH - data: '0x18160ddd', // web3.eth.abi.encodeFunctionSignature("totalSupply()") -}; +```typescript +console.log(`Started Transfer: `, srcTxids); -(async () => { - const latestBlock: string = ( - await axios.post(rpc, { - method: 'eth_getBlockByNumber', - params: ['latest', false], - id: 1, - jsonrpc: '2.0', - }) - ).data?.result?.number; - if (!latestBlock) { - console.error(`❌ Invalid block returned`); - return; - } - console.log('Latest Block: ', latestBlock, `(${BigInt(latestBlock)})`); - const targetResponse = await axios.post(rpc, { - method: 'eth_call', - params: [callData, latestBlock], - id: 1, - jsonrpc: '2.0', - }); - // console.log(finalizedResponse.data); - if (targetResponse.data.error) { - console.error(`❌ ${targetResponse.data.error.message}`); - } - const targetResult = targetResponse.data?.result; - console.log('Target Result: ', targetResult, `(${BigInt(targetResult)})`); - // Form the query request - const request = new QueryRequest( - 0, // Nonce - [ - new PerChainQueryRequest( - 2, // Ethereum Wormhole Chain ID - new EthCallQueryRequest(latestBlock, [callData]) - ), - ] - ); - console.log(JSON.stringify(request, undefined, 2)); - const mock = new QueryProxyMock({ 2: rpc }); - const mockData = await mock.mock(request); - console.log(mockData); - const mockQueryResponse = QueryResponse.from(mockData.bytes); - const mockQueryResult = ( - mockQueryResponse.responses[0].response as EthCallQueryResponse - ).results[0]; - console.log( - `Mock Query Result: ${mockQueryResult} (${BigInt(mockQueryResult)})` - ); -})(); + process.exit(0); ``` -### Fork Testing +You can find the full code for the automatic USDC transfer script below: -It is common to test against a local fork of Mainnet with something like +??? code "`automatic-transfer.ts`" + ```typescript + import { wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { getSigner } from '../helpers/helpers'; -```jsx -anvil --fork-url https://ethereum.publicnode.com -``` +(async function () { + // Initialize the Wormhole object for the Testnet environment and add supported chains (evm and solana) + const wh = await wormhole('Testnet', [evm, solana]); -In order for mock requests to verify against the Mainnet Core Contract, you need to replace the current Guardian set with the single Devnet key used by the mock. + // Set up source and destination chains + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Sepolia'); -Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. + // Configure the signers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -```jsx -npx @wormhole-foundation/wormhole-cli evm hijack -a 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B -g 0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe -``` + // Define the transfer amount (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) + const amt = 100_000_001n; -If you are using `EthCallWithFinality`, you will need to mine additional blocks (32 if using [Anvil](https://book.getfoundry.sh/anvil/){target=\_blank}) after the latest transaction for it to become finalized. Anvil supports [auto-mining](https://book.getfoundry.sh/reference/anvil/#mining-modes){target=\_blank} with the `-b` flag if you want to test code that waits naturally for the chain to advance. For integration tests, you may want to simply `anvil_mine` with `0x20`. + const automatic = true; -## Make a Query Request + // Create the Circle transfer object (USDC-only) + const xfer = await wh.circleTransfer( + amt, + source.address, + destination.address, + automatic + ); -The standardized means of making a `QueryRequest` with an API key is as follows: + console.log('Circle Transfer object created:', xfer); -```jsx -const serialized = request.serialize(); -const proxyResponse = (await axios.post)( - QUERY_URL, - { - bytes: Buffer.from(serialized).toString('hex'), - }, - { headers: { 'X-API-Key': YOUR_API_KEY } } -); - + // Initiate the transfer on the source chain (Avalanche) + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); + + process.exit(0); +})(); + ``` + +### Run Automatic Transfer + +Assuming you have created a new `automatic-transfer.ts` file for automatic transfers under the `src` directory, use the following command to run it with `ts-node`: + +```bash +npx ts-node src/automatic-transfer.ts ``` -Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. +The automatic relayer will take care of fetching the attestation and completing the transfer for you. -A Testnet Query Proxy is available at `https://testnet.query.wormhole.com/v1/query` +## Resources -A Mainnet Query Proxy is available at `https://query.wormhole.com/v1/query` +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in [Wormhole's demo GitHub repository](https://github.com/wormhole-foundation/demo-cctp-transfer){target=\_blank}. The repository includes all the example scripts and configurations needed to perform USDC cross-chain transfers, including manual, automatic, and partial transfers using the Wormhole SDK and Circle's CCTP. -## Verify a Query Response On-Chain +## Conclusion -A [`QueryResponseLib` library](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/QueryResponse.sol){target=\_blank} is provided to assist with verifying query responses. You can begin by installing the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} with the following command: +In this tutorial, you’ve gained hands-on experience with Circle’s CCTP and the Wormhole SDK. You’ve learned to perform manual and automatic USDC transfers across multiple chains and recover partial transfers if needed. -```bash -forge install wormhole-foundation/wormhole-solidity-sdk -``` +By following these steps, you've learned how to: -Broadly, using a query response on-chain comes down to three main steps: +- Set up cross-chain transfers for native USDC between supported chains +- Handle both manual and automatic relaying of transactions +- Recover and complete incomplete transfers using the transaction hash and the destination chain’s signer +--- END CONTENT --- - 1. Parse and verify the query response - 2. The `parseAndVerifyQueryResponse` handles verifying the Guardian signatures against the current Guardian set stored in the Core bridge contract - 3. Validate the request details. This may be different for every integrator depending on their use case, but generally checks the following: - - Is the request against the expected chain? - - Is the request of the expected type? The `parseEthCall` helpers perform this check when parsing - - Is the resulting block number and time expected? Some consumers might require that a block number be higher than the last, or the block time be within the last 5 minutes. `validateBlockNum` and `validateBlockTime` can help with the checks - - Is the request for the expected contract and function signature? The `validateMultipleEthCallData` can help with non-parameter-dependent cases - - Is the result of the expected length for the expected result type? - 4. Run `abi.decode` on the result +Doc-Content: https://wormhole.com/docs/products/connect/concepts/routes/ +--- BEGIN CONTENT --- +--- +title: Routes +description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. +categories: Connect, Transfer +--- -See the [QueryDemo](https://github.com/wormholelabs-xyz/example-queries-demo/blob/main/src/QueryDemo.sol){target=\_blank} contract for an example and read the docstrings of the preceding methods for detailed usage instructions. +## Routes Overview {: #routes-overview} -??? code "View the complete `QueryDemo`" - ```solidity - // contracts/query/QueryDemo.sol -// SPDX-License-Identifier: Apache 2 +This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/products/connect/configuration/data/){target=\_blank}. -pragma solidity ^0.8.0; +Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. -import "wormhole-solidity-sdk/libraries/BytesParsing.sol"; -import "wormhole-solidity-sdk/interfaces/IWormhole.sol"; -import "wormhole-solidity-sdk/QueryResponse.sol"; +When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/products/connect/reference/support-matrix/){target=\_blank} to see under which exact conditions the routes appear. -error InvalidOwner(); -// @dev for the onlyOwner modifier -error InvalidCaller(); -error InvalidCalldata(); -error InvalidForeignChainID(); -error ObsoleteUpdate(); -error StaleUpdate(); -error UnexpectedResultLength(); -error UnexpectedResultMismatch(); +## Token Bridge Routes {: #token-bridge-routes} -/// @dev QueryDemo is an example of using the QueryResponse library to parse and verify Cross Chain Query (CCQ) responses. -contract QueryDemo is QueryResponse { - using BytesParsing for bytes; +The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. - struct ChainEntry { - uint16 chainID; - address contractAddress; - uint256 counter; - uint256 blockNum; - uint256 blockTime; - } +#### Manual Route {: #manual-route} - address private immutable owner; - uint16 private immutable myChainID; - mapping(uint16 => ChainEntry) private counters; - uint16[] private foreignChainIDs; +The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. - bytes4 public GetMyCounter = bytes4(hex"916d5743"); +#### Automatic Route {: #automatic-route} - constructor(address _owner, address _wormhole, uint16 _myChainID) QueryResponse(_wormhole) { - if (_owner == address(0)) { - revert InvalidOwner(); - } - owner = _owner; +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. - myChainID = _myChainID; - counters[_myChainID] = ChainEntry(_myChainID, address(this), 0, 0, 0); - } +## CCTP Routes (USDC) {: #cctp-routes-usdc} + +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. - // updateRegistration should be used to add the other chains and to set / update contract addresses. - function updateRegistration(uint16 _chainID, address _contractAddress) public onlyOwner { - if (counters[_chainID].chainID == 0) { - foreignChainIDs.push(_chainID); - counters[_chainID].chainID = _chainID; - } +Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. - counters[_chainID].contractAddress = _contractAddress; - } +#### Manual Route {: #manual-route-cctp} - // getMyCounter (call signature 916d5743) returns the counter value for this chain. It is meant to be used in a cross chain query. - function getMyCounter() public view returns (uint256) { - return counters[myChainID].counter; - } +This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. - // getState() returns this chain's view of all the counters. It is meant to be used in the front end. - function getState() public view returns (ChainEntry[] memory) { - ChainEntry[] memory ret = new ChainEntry[](foreignChainIDs.length + 1); - ret[0] = counters[myChainID]; - uint256 length = foreignChainIDs.length; +#### Automatic Route {: #automatic-route-cctp} - for (uint256 i = 0; i < length;) { - ret[i + 1] = counters[foreignChainIDs[i]]; - unchecked { - ++i; - } - } +Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. - return ret; - } +## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} - // @notice Takes the cross chain query response for the other counters, stores the results for the other chains, and updates the counter for this chain. - function updateCounters(bytes memory response, IWormhole.Signature[] memory signatures) public { - ParsedQueryResponse memory r = parseAndVerifyQueryResponse(response, signatures); - uint256 numResponses = r.responses.length; - if (numResponses != foreignChainIDs.length) { - revert UnexpectedResultLength(); - } +[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/products/connect/configuration/data/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. - for (uint256 i = 0; i < numResponses;) { - // Create a storage pointer for frequently read and updated data stored on the blockchain - ChainEntry storage chainEntry = counters[r.responses[i].chainId]; - if (chainEntry.chainID != foreignChainIDs[i]) { - revert InvalidForeignChainID(); - } +#### Manual Route {: #manual-route-ntt} - EthCallQueryResponse memory eqr = parseEthCallQueryResponse(r.responses[i]); +This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. - // Validate that update is not obsolete - validateBlockNum(eqr.blockNum, chainEntry.blockNum); +#### Automatic Route {: #automatic-route-ntt} - // Validate that update is not stale - validateBlockTime(eqr.blockTime, block.timestamp - 300); +Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. - if (eqr.result.length != 1) { - revert UnexpectedResultMismatch(); - } +## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} - // Validate addresses and function signatures - address[] memory validAddresses = new address[](1); - bytes4[] memory validFunctionSignatures = new bytes4[](1); - validAddresses[0] = chainEntry.contractAddress; - validFunctionSignatures[0] = GetMyCounter; +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). - validateMultipleEthCallData(eqr.result, validAddresses, validFunctionSignatures); +#### Automatic Route {: #automatic-route-eth} - require(eqr.result[0].result.length == 32, "result is not a uint256"); +Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. - chainEntry.blockNum = eqr.blockNum; - chainEntry.blockTime = eqr.blockTime / 1_000_000; - chainEntry.counter = abi.decode(eqr.result[0].result, (uint256)); +## USDT Bridge Route {: #usdt-bridge-route} - unchecked { - ++i; - } - } +Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. - counters[myChainID].blockNum = block.number; - counters[myChainID].blockTime = block.timestamp; - counters[myChainID].counter += 1; - } +#### Automatic Route {: #automatic-route-usdt} - modifier onlyOwner() { - if (owner != msg.sender) { - revert InvalidOwner(); - } - _; - } -} - ``` +Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. -## Submit a Query Response On-Chain +## tBTC Route {: #tbtc-route} -The `QueryProxyQueryResponse` result requires a slight tweak when submitting to the contract to match the format of `function parseAndVerifyQueryResponse(bytes memory response, IWormhole.Signature[] memory signatures)`. A helper function, `signaturesToEvmStruct`, is provided in the SDK for this. +You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). -This example submits the transaction to the demo contract: +Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. -```jsx -const tx = await contract.updateCounters( - `0x${response.data.bytes}`, - signaturesToEvmStruct(response.data.signatures) -); -``` +#### Manual Route {: #manual-route-tbtc} + +This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/reference/chain-ids/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/configuration-v0/ --- BEGIN CONTENT --- --- -title: Chain IDs -description: This page documents the Wormhole-specific chain IDs for each chain and contrasts them to the more commonly referenced EVM chain IDs originating in EIP-155. -categories: Reference +title: Configure Your Connect Widget v0 +description: Configure Wormhole Connect v0 for React or HTML, set themes, define tokens, networks, and customize RPC endpoints for optimized blockchain interactions. --- -# Chain IDs +# Configure Your Connect Widget -The following table documents the chain IDs used by Wormhole and places them alongside the more commonly referenced [EVM Chain IDs](https://chainlist.org/){target=\_blank}. +## Introduction {: #introduction } + +Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. + +This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. !!! note - Please note, Wormhole chain IDs are different than the more commonly referenced EVM [chain IDs](https://eips.ethereum.org/EIPS/eip-155){target=\_blank}, specified in the Mainnet and Testnet ID columns. + For documentation on the latest version of Connect, please refer to the current [configuration documentation](/docs/products/connect/configuration/data/){target=\_blank}. If you are looking to upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/products/connect/guides/upgrade/){target=\_blank} for detailed instructions. - - +## Get Started -=== "Mainnet" +Configure the Wormhole Connect React component by passing a `WormholeConnectConfig` object as the `config` attribute. If using the hosted version, provide `config` and `theme` as JSON-serialized strings on the mount point. - | Ethereum | 2 | 1 | -| Solana | 1 | Mainnet Beta-5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d | -| Algorand | 8 | mainnet-v1.0 | -| Aptos | 22 | 1 | -| Arbitrum | 23 | Arbitrum One-42161 | -| Avalanche | 6 | C-Chain-43114 | -| Base | 30 | Base-8453 | -| Berachain | 39 | | -| Blast | 36 | 81457 | -| BNB Smart Chain | 4 | 56 | -| Celestia | 4004 | celestia | -| Celo | 14 | 42220 | -| Cosmos Hub | 4000 | cosmoshub-4 | -| Dymension | 4007 | dymension_1100-1 | -| Evmos | 4001 | evmos_9001-2 | -| Fantom | 10 | 250 | -| Gnosis | 25 | 100 | -| HyperEVM | 47 | | -| Injective | 19 | injective-1 | -| Ink | 46 | | -| Kaia | 13 | 8217 | -| Kujira | 4002 | kaiyo-1 | -| Linea | 38 | 59144 | -| Mantle | 35 | 5000 | -| Mezo | 50 | | -| Monad | 48 | | -| Moonbeam | 16 | 1284 | -| NEAR | 15 | mainnet | -| Neon | 17 | 245022934 | -| Neutron | 4003 | neutron-1 | -| Noble | 4009 | noble-1 | -| Optimism | 24 | 10 | -| Osmosis | 20 | osmosis-1 | -| Polygon | 5 | 137 | -| Provenance | 4008 | pio-mainnet-1 | -| Pythnet | 26 | | -| Scroll | 34 | 534352 | -| SEDA | 4006 | | -| Sei | 32 | pacific-1 | -| Seievm | 40 | | -| SNAXchain | 43 | 2192 | -| Sonic | 52 | 146 | -| Stargaze | 4005 | stargaze-1 | -| Sui | 21 | 35834a8a | -| Terra 2.0 | 18 | phoenix-1 | -| Unichain | 44 | | -| World Chain | 45 | 480 | -| X Layer | 37 | 196 | +=== "React" -=== "Testnet" + ```ts + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; + +const config: WormholeConnectConfig = { + networks: ['ethereum', 'polygon', 'solana'], + tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], + rpcs: { + ethereum: 'https://rpc.ankr.com/eth', + solana: 'https://rpc.ankr.com/solana', + } +} + + + ``` - | Ethereum Holesky | 10006 | Holesky-17000 | -| Ethereum Sepolia | 10002 | Sepolia-11155111 | -| Solana | 1 | Devnet-EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG | -| Algorand | 8 | testnet-v1.0 | -| Aptos | 22 | 2 | -| Arbitrum Sepolia | 10003 | Sepolia-421614 | -| Avalanche | 6 | Fuji-43113 | -| Base Sepolia | 10004 | Base Sepolia-84532 | -| Berachain | 39 | 80084 | -| Blast | 36 | 168587773 | -| BNB Smart Chain | 4 | 97 | -| Celestia | 4004 | mocha-4 | -| Celo | 14 | Alfajores-44787 | -| Cosmos Hub | 4000 | theta-testnet-001 | -| Dymension | 4007 | | -| Evmos | 4001 | evmos_9000-4 | -| Fantom | 10 | 4002 | -| Gnosis | 25 | Chiado-10200 | -| HyperEVM | 47 | 998 | -| Injective | 19 | injective-888 | -| Ink | 46 | 763373 | -| Kaia | 13 | Kairos-1001 | -| Kujira | 4002 | harpoon-4 | -| Linea | 38 | 59141 | -| Mantle | 35 | Sepolia-5003 | -| Mezo | 50 | 31611 | -| Monad | 48 | 10143 | -| Moonbeam | 16 | Moonbase-Alphanet-1287 | -| NEAR | 15 | testnet | -| Neon | 17 | 245022940 | -| Neutron | 4003 | pion-1 | -| Noble | 4009 | grand-1 | -| Optimism Sepolia | 10005 | Optimism Sepolia-11155420 | -| Osmosis | 20 | osmo-test-5 | -| Polygon Amoy | 10007 | Amoy-80002 | -| Provenance | 4008 | | -| Pythnet | 26 | | -| Scroll | 34 | Sepolia-534351 | -| SEDA | 4006 | seda-1-testnet | -| Sei | 32 | atlantic-2 | -| Seievm | 40 | | -| SNAXchain | 43 | 13001 | -| Sonic | 52 | 57054 | -| Stargaze | 4005 | | -| Sui | 21 | 4c78adac | -| Terra 2.0 | 18 | pisco-1 | -| Unichain | 44 | Unichain Sepolia-1301 | -| World Chain | 45 | 4801 | -| X Layer | 37 | 195 | - ---- END CONTENT --- +=== "HTML Tags" -Doc-Content: https://wormhole.com/docs/build/reference/consistency-levels/ ---- BEGIN CONTENT --- ---- -title: Wormhole Finality | Consistency Levels -description: This page documents how long to wait for finality before signing, based on each chain’s consistency (finality) level and consensus mechanism. -categories: Reference ---- + ```html +
+ ``` -# Wormhole Finality +## Examples {: #examples } -The following table documents each chain's `consistencyLevel` values (i.e., finality reached before signing). The consistency level defines how long the Guardians should wait before signing a VAA. The finalization time depends on the specific chain's consensus mechanism. The consistency level is a `u8`, so any single byte may be used. However, a small subset has particular meanings. If the `consistencyLevel` isn't one of those specific values, the `Otherwise` column describes how it's interpreted. +Below are some examples of different ways you can configure Connect. See `WormholeConnectConfig` in the below file for a full view of the supported configuration parameters. - - -| Ethereum | 200 | 201 | | finalized | ~ 19min | Details | -| Solana | | 0 | 1 | | ~ 14s | Details | -| Algorand | | | 0 | | ~ 4s | Details | -| Aptos | | | 0 | | ~ 4s | Details | -| Arbitrum | 200 | 201 | | finalized | ~ 18min | Details | -| Avalanche | 200 | | | finalized | ~ 2s | Details | -| Base | 200 | 201 | | finalized | ~ 18min | | -| Berachain | 200 | | | finalized | ~ 4s | | -| Blast | 200 | 201 | | finalized | ~ 18min | | -| BNB Smart Chain | 200 | 201 | | finalized | ~ 48s | Details | -| Celestia | | | 0 | | ~ 5s | | -| Celo | 200 | | | finalized | ~ 10s | | -| Cosmos Hub | | | 0 | | ~ 5s | | -| Dymension | | | 0 | | ~ 5s | | -| Evmos | | | 0 | | ~ 2s | | -| Fantom | 200 | | | finalized | ~ 5s | | -| Injective | | | 0 | | ~ 3s | | -| Ink | | | 0 | | ~ 9min | | -| Kaia | 200 | | | finalized | ~ 1s | | -| Kujira | | | 0 | | ~ 3s | | -| Mantle | 200 | 201 | | finalized | ~ 18min | | -| Mezo | | | 0 | | ~ 8s | | -| Monad | | | 0 | | ~ 2s | | -| Moonbeam | 200 | 201 | | finalized | ~ 24s | Details | -| NEAR | | | 0 | | ~ 2s | Details | -| Neutron | | | 0 | | ~ 5s | | -| Optimism | 200 | 201 | | finalized | ~ 18min | | -| Osmosis | | | 0 | | ~ 6s | | -| Polygon | 200 | | | finalized | ~ 66s | Details | -| Scroll | 200 | | | finalized | ~ 16min | | -| Sei | | | 0 | | ~ 1s | | -| Sonic | | | 0 | | ~ 1s | | -| Stargaze | | | 0 | | ~ 5s | | -| Sui | | | 0 | | ~ 3s | Details | -| Terra 2.0 | | | 0 | | ~ 6s | | -| Unichain | 200 | 201 | | finalized | ~ 18min | | -| World Chain | | | 0 | | ~ 18min | | -| X Layer | 200 | 201 | | finalized | ~ 16min | | - ---- END CONTENT --- +??? code "View `WormholeConnectConfig`" + ```ts + import { + ChainName, + WormholeContext, + WormholeConfig, + ChainResourceMap, +} from 'sdklegacy'; +import MAINNET from './mainnet'; +import TESTNET from './testnet'; +import DEVNET from './devnet'; +import type { WormholeConnectConfig } from './types'; +import { + Network, + InternalConfig, + Route, + WrappedTokenAddressCache, +} from './types'; +import { + mergeCustomTokensConfig, + mergeNttGroups, + validateDefaults, +} from './utils'; +import { wrapEventHandler } from './events'; -Doc-Content: https://wormhole.com/docs/build/reference/contract-addresses/ ---- BEGIN CONTENT --- ---- -title: Contract Addresses -description: This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. -categories: Reference ---- +import { SDKConverter } from './converter'; -# Contract Addresses +import { + wormhole as getWormholeV2, + Wormhole as WormholeV2, + Network as NetworkV2, + Token as TokenV2, + Chain as ChainV2, + ChainTokens as ChainTokensV2, + WormholeConfigOverrides as WormholeConfigOverridesV2, +} from '@wormhole-foundation/sdk'; -## Core Contracts +import '@wormhole-foundation/sdk/addresses'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import aptos from '@wormhole-foundation/sdk/aptos'; +import sui from '@wormhole-foundation/sdk/sui'; +import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; +import algorand from '@wormhole-foundation/sdk/algorand'; - - +export function buildConfig( + customConfig?: WormholeConnectConfig +): InternalConfig { + const network = ( + customConfig?.network || + customConfig?.env || // TODO remove; deprecated + import.meta.env.REACT_APP_CONNECT_ENV?.toLowerCase() || + 'mainnet' + ).toLowerCase() as Network; -=== "Mainnet" + if (!['mainnet', 'testnet', 'devnet'].includes(network)) + throw new Error(`Invalid env "${network}"`); - | Ethereum | 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B | -| Solana | worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth | -| Algorand | 842125965 | -| Aptos | 0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625 | -| Arbitrum | 0xa5f208e072434bC67592E4C49C1B991BA79BCA46 | -| Avalanche | 0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c | -| Base | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Berachain | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | -| Blast | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| BNB Smart Chain | 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B | -| Celo | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Fantom | 0x126783A6Cb203a3E35344528B26ca3a0489a1485 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| HyperEVM | 0x7C0faFc4384551f063e05aee704ab943b8B53aB3 | -| Injective | inj17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9l2q74d | -| Ink | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | -| Kaia | 0x0C21603c4f3a6387e241c0091A7EA39E43E90bb7 | -| Mantle | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Moonbeam | 0xC8e2b0cD52Cf01b0Ce87d389Daa3d414d4cE29f3 | -| NEAR | contract.wormhole_crypto.near | -| Neutron | neutron16rerygcpahqcxx5t8vjla46ym8ccn7xz7rtc6ju5ujcd36cmc7zs9zrunh | -| Optimism | 0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722 | -| Polygon | 0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7 | -| Pythnet | H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU | -| Scroll | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sei | sei1gjrrme22cyha4ht2xapn3f08zzw6z3d4uxx6fyy9zd5dyr3yxgzqqncdqn | -| Seievm | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | -| SNAXchain | 0xc1BA3CC4bFE724A08FbbFbF64F8db196738665f4 | -| Sui | 0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c | -| Terra 2.0 | terra12mrnzvhx3rpej6843uge2yyfppfyd3u9c3uq223q8sl48huz9juqffcnhp | -| Unichain | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | -| World Chain | 0xcbcEe4e081464A15d8Ad5f58BB493954421eB506 | -| X Layer | 0x194B123c5E96B9b2E49763619985790Dc241CAC0 | + const networkData = { MAINNET, DEVNET, TESTNET }[network.toUpperCase()]!; -=== "Testnet" + const tokens = mergeCustomTokensConfig( + networkData.tokens, + customConfig?.tokensConfig + ); - | Ethereum Holesky | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | -| Ethereum Sepolia | 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 | -| Solana | 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 | -| Algorand | 86525623 | -| Aptos | 0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625 | -| Arbitrum Sepolia | 0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35 | -| Avalanche | 0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C | -| Base Sepolia | 0x79A1027a6A159502049F10906D333EC57E95F083 | -| Berachain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| Blast | 0x473e002D7add6fB67a4964F13bFd61280Ca46886 | -| BNB Smart Chain | 0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D | -| Celo | 0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56 | -| Fantom | 0x1BB3B4119b7BA9dfad76B0545fb3F531383c3bB7 | -| Gnosis | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| HyperEVM | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| Injective | inj1xx3aupmgv3ce537c0yce8zzd3sz567syuyedpg | -| Ink | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| Kaia | 0x1830CC6eE66c84D2F177B94D544967c774E624cA | -| Linea | 0x79A1027a6A159502049F10906D333EC57E95F083 | -| Mantle | 0x376428e7f26D5867e69201b275553C45B09EE090 | -| Mezo | 0x268557122Ffd64c85750d630b716471118F323c8 | -| Monad | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| Moonbeam | 0xa5B7D85a8f27dd7907dc8FdC21FA5657D5E2F901 | -| NEAR | wormhole.wormhole.testnet | -| Neon | 0x268557122Ffd64c85750d630b716471118F323c8 | -| Neutron | neutron1enf63k37nnv9cugggpm06mg70emcnxgj9p64v2s8yx7a2yhhzk2q6xesk4 | -| Optimism Sepolia | 0x31377888146f3253211EFEf5c676D41ECe7D58Fe | -| Osmosis | osmo1hggkxr0hpw83f8vuft7ruvmmamsxmwk2hzz6nytdkzyup9krt0dq27sgyx | -| Polygon Amoy | 0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35 | -| Pythnet | EUrRARh92Cdc54xrDn6qzaqjA77NRrCcfbr8kPwoTL4z | -| Scroll | 0x055F47F1250012C6B20c436570a76e52c17Af2D5 | -| Sei | sei1nna9mzp274djrgzhzkac2gvm3j27l402s4xzr08chq57pjsupqnqaj0d5s | -| Seievm | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| SNAXchain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| Sui | 0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790 | -| Terra 2.0 | terra19nv3xr5lrmmr7egvrk2kqgw4kcn43xrtd5g0mpgwwvhetusk4k7s66jyv0 | -| Unichain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | -| World Chain | 0xe5E02cD12B6FcA153b0d7fF4bF55730AE7B3C93A | -| X Layer | 0xA31aa3FDb7aF7Db93d18DDA4e19F811342EDF780 | + const sdkConfig = WormholeContext.getConfig(network); -=== "Devnet" + const rpcs = Object.assign( + {}, + sdkConfig.rpcs, + networkData.rpcs, + customConfig?.rpcs + ); - | Ethereum | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | -| Solana | Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o | -| Algorand | 1004 | -| Aptos | 0xde0036a9600559e295d5f6802ef6f3f802f510366e0c23912b0655d972166017 | -| BNB Smart Chain | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | -| NEAR | wormhole.test.near | -| Sui | 0x5a5160ca3c2037f4b4051344096ef7a48ebf4400b3f385e57ea90e1628a8bde0 | -| Terra 2.0 | terra14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssrc8au | - + const wh = getWormholeContext(network, sdkConfig, rpcs); -## Token Bridge + if (customConfig?.bridgeDefaults) { + validateDefaults(customConfig.bridgeDefaults, networkData.chains, tokens); + } - - + const sdkConverter = new SDKConverter(wh); -=== "Mainnet" + return { + wh, + sdkConfig, + sdkConverter, - | Ethereum | 0x3ee18B2214AFF97000D974cf647E7C347E8fa585 | -| Solana | wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb | -| Algorand | 842126029 | -| Aptos | 0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f | -| Arbitrum | 0x0b2402144Bb366A632D14B83F244D2e0e21bD39c | -| Avalanche | 0x0e082F06FF657D94310cB8cE8B0D9a04541d8052 | -| Base | 0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627 | -| Berachain | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | -| Blast | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | -| BNB Smart Chain | 0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7 | -| Celo | 0x796Dff6D74F3E27060B71255Fe517BFb23C93eed | -| Fantom | 0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2 | -| Injective | inj1ghd753shjuwexxywmgs4xz7x2q732vcnxxynfn | -| Ink | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | -| Kaia | 0x5b08ac39EAED75c0439FC750d9FE7E1F9dD0193F | -| Mantle | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | -| Moonbeam | 0xb1731c586ca89a23809861c6103f0b96b3f57d92 | -| NEAR | contract.portalbridge.near | -| Optimism | 0x1D68124e65faFC907325e3EDbF8c4d84499DAa8b | -| Polygon | 0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE | -| Scroll | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | -| Sei | sei1smzlm9t79kur392nu9egl8p8je9j92q4gzguewj56a05kyxxra0qy0nuf3 | -| Seievm | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | -| SNAXchain | 0x8B94bfE456B48a6025b92E11Be393BAa86e68410 | -| Sui | 0xc57508ee0d4595e5a8728974a4a93a787d38f339757230d441e895422c07aba9 | -| Terra 2.0 | terra153366q50k7t8nn7gec00hg66crnhkdggpgdtaxltaq6xrutkkz3s992fw9 | -| Unichain | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | -| World Chain | 0xc309275443519adca74c9136b02A38eF96E3a1f6 | -| X Layer | 0x5537857664B0f9eFe38C9f320F75fEf23234D904 | + v2Network: sdkConverter.toNetworkV2(network), -=== "Testnet" + network, + isMainnet: network === 'mainnet', + // External resources + rpcs, + rest: Object.assign( + {}, + sdkConfig.rest, + networkData.rest, + customConfig?.rest + ), + graphql: Object.assign({}, networkData.graphql, customConfig?.graphql), + wormholeApi: { + mainnet: 'https://api.wormholescan.io/', + testnet: 'https://api.testnet.wormholescan.io/', + devnet: '', + }[network], + wormholeRpcHosts: { + mainnet: [ + 'https://wormhole-v2-mainnet-api.mcf.rocks', + 'https://wormhole-v2-mainnet-api.chainlayer.network', + 'https://wormhole-v2-mainnet-api.staking.fund', + ], + testnet: [ + 'https://guardian.testnet.xlabs.xyz', + 'https://guardian-01.testnet.xlabs.xyz', + 'https://guardian-02.testnet.xlabs.xyz', + ], + devnet: ['http://localhost:7071'], + }[network], + coinGeckoApiKey: customConfig?.coinGeckoApiKey, - | Ethereum Holesky | 0x76d093BbaE4529a342080546cAFEec4AcbA59EC6 | -| Ethereum Sepolia | 0xDB5492265f6038831E89f495670FF909aDe94bd9 | -| Solana | DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe | -| Algorand | 86525641 | -| Aptos | 0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f | -| Arbitrum Sepolia | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | -| Avalanche | 0x61E44E506Ca5659E6c0bba9b678586fA2d729756 | -| Base Sepolia | 0x86F55A04690fd7815A3D802bD587e83eA888B239 | -| Berachain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | -| Blast | 0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2 | -| BNB Smart Chain | 0x9dcF9D205C9De35334D646BeE44b2D2859712A09 | -| Celo | 0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153 | -| Fantom | 0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8 | -| HyperEVM | 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 | -| Injective | inj1q0e70vhrv063eah90mu97sazhywmeegp7myvnh | -| Ink | 0x376428e7f26D5867e69201b275553C45B09EE090 | -| Kaia | 0xC7A13BE098720840dEa132D860fDfa030884b09A | -| Linea | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | -| Mantle | 0x75Bfa155a9D7A3714b0861c8a8aF0C4633c45b5D | -| Mezo | 0xA31aa3FDb7aF7Db93d18DDA4e19F811342EDF780 | -| Monad | 0xF323dcDe4d33efe83cf455F78F9F6cc656e6B659 | -| Moonbeam | 0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96 | -| NEAR | token.wormhole.testnet | -| Neon | 0xEe3dB83916Ccdc3593b734F7F2d16D630F39F1D0 | -| Optimism Sepolia | 0x99737Ec4B815d816c49A385943baf0380e75c0Ac | -| Polygon Amoy | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | -| Scroll | 0x22427d90B7dA3fA4642F7025A854c7254E4e45BF | -| Sei | sei1jv5xw094mclanxt5emammy875qelf3v62u4tl4lp5nhte3w3s9ts9w9az2 | -| Seievm | 0x23908A62110e21C04F3A4e011d24F901F911744A | -| SNAXchain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | -| Sui | 0x6fb10cdb7aa299e9a4308752dadecb049ff55a892de92992a1edbd7912b3d6da | -| Terra 2.0 | terra1c02vds4uhgtrmcw7ldlg75zumdqxr8hwf7npseuf2h58jzhpgjxsgmwkvk | -| Unichain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | -| World Chain | 0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2 | -| X Layer | 0xdA91a06299BBF302091B053c6B9EF86Eff0f930D | + // Callbacks + triggerEvent: wrapEventHandler(customConfig?.eventHandler), + validateTransfer: customConfig?.validateTransferHandler, -=== "Devnet" + // White lists + chains: networkData.chains, + chainsArr: Object.values(networkData.chains).filter((chain) => { + return customConfig?.networks + ? customConfig.networks!.includes(chain.key) + : true; + }), + tokens, + tokensArr: Object.values(tokens).filter((token) => { + return customConfig?.tokens + ? customConfig.tokens!.includes(token.key) + : true; + }), - | Ethereum | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | -| Solana | B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE | -| Algorand | 1006 | -| Aptos | 0x84a5f374d29fc77e370014dce4fd6a55b58ad608de8074b0be5571701724da31 | -| BNB Smart Chain | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | -| NEAR | token.test.near | -| Sui | 0xa6a3da85bbe05da5bfd953708d56f1a3a023e7fb58e5a824a3d4de3791e8f690 | -| Terra 2.0 | terra1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrquka9l6 | - + // For token bridge ^_^ + wrappedTokenAddressCache: new WrappedTokenAddressCache( + tokens, + sdkConverter + ), -## Wormhole Relayer + gasEstimates: networkData.gasEstimates, + // TODO: routes that aren't supported yet are disabled + routes: (customConfig?.routes ?? Object.values(Route)).filter((r) => + [ + Route.Bridge, + Route.Relay, + Route.NttManual, + Route.NttRelay, + Route.CCTPManual, + Route.CCTPRelay, + ].includes(r as Route) + ), - - + // UI details + cta: customConfig?.cta, + explorer: customConfig?.explorer, + attestUrl: { + mainnet: 'https://portalbridge.com/advanced-tools/#/register', + devnet: '', + testnet: + 'https://wormhole-foundation.github.io/example-token-bridge-ui/#/register', + }[network], + bridgeDefaults: customConfig?.bridgeDefaults, + cctpWarning: customConfig?.cctpWarning?.href || '', + pageHeader: customConfig?.pageHeader, + pageSubHeader: customConfig?.pageSubHeader, + menu: customConfig?.menu ?? [], + searchTx: customConfig?.searchTx, + moreTokens: customConfig?.moreTokens, + moreNetworks: customConfig?.moreNetworks, + partnerLogo: customConfig?.partnerLogo, + walletConnectProjectId: + customConfig?.walletConnectProjectId ?? + import.meta.env.REACT_APP_WALLET_CONNECT_PROJECT_ID, + showHamburgerMenu: customConfig?.showHamburgerMenu ?? false, + previewMode: !!customConfig?.previewMode, -=== "Mainnet" + // Route options + ethBridgeMaxAmount: customConfig?.ethBridgeMaxAmount ?? 5, + wstETHBridgeMaxAmount: customConfig?.wstETHBridgeMaxAmount ?? 5, - | Ethereum | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Arbitrum | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Avalanche | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Base | 0x706f82e9bb5b0813501714ab5974216704980e31 | -| Berachain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Blast | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| BNB Smart Chain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Celo | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Fantom | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Ink | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Kaia | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Mantle | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Moonbeam | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Optimism | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | -| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | - -=== "Testnet" - - | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | -| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | -| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | -| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | -| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | -| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | -| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | - -=== "Devnet" - - | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | -| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | - - -## CCTP - - - - -=== "Mainnet" + // NTT config + nttGroups: mergeNttGroups( + tokens, + networkData.nttGroups, + customConfig?.nttGroups + ), - | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | -| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | -| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | -| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | + // Guardian set + guardianSet: networkData.guardianSet, -=== "Testnet" + // Render redesign views + useRedesign: customConfig?.useRedesign, + }; +} - | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | -| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +// Running buildConfig with no argument generates the default configuration +const config = buildConfig(); +export default config; -=== "Devnet" +// TODO SDKV2: REMOVE +export function getWormholeContext( + network: Network, + sdkConfig: WormholeConfig, + rpcs: ChainResourceMap +): WormholeContext { + const wh: WormholeContext = new WormholeContext(network, { + ...sdkConfig, + ...{ rpcs }, + }); - N/A - - + return wh; +} -## Settlement Token Router +export function getDefaultWormholeContext(network: Network): WormholeContext { + const sdkConfig = WormholeContext.getConfig(network); + const networkData = { mainnet: MAINNET, devnet: DEVNET, testnet: TESTNET }[ + network + ]!; -=== "Mainnet" + const rpcs = Object.assign({}, sdkConfig.rpcs, networkData.rpcs); - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Ethereum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Solana | `28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe` | - | Arbitrum | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Avalanche | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Base | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Optimism | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | - | Polygon | `0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47` | + return getWormholeContext(network, sdkConfig, rpcs); +} -=== "Testnet" +export async function getWormholeContextV2(): Promise> { + if (config.v2Wormhole) return config.v2Wormhole; + config.v2Wormhole = await newWormholeContextV2(); + return config.v2Wormhole; +} - | Chain Name | Contract Address | - |----------------------|-------------------------------------------------| - | Solana | `tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md` | - | Arbitrum Sepolia | `0xe0418C44F06B0b0D7D1706E01706316DBB0B210E` | - | Optimism Sepolia | `0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8` | - +export async function newWormholeContextV2(): Promise> { + const v2Config: WormholeConfigOverridesV2 = { chains: {} }; -## Read-Only Deployments + for (const key in config.chains) { + const chainV1 = key as ChainName; + const chainConfigV1 = config.chains[chainV1]!; -=== "Mainnet" + const chainContextV1 = chainConfigV1.context; - | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | -| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | -| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | -| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | -| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | -| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | -| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | + const chainV2 = config.sdkConverter.toChainV2( + chainV1 as ChainName + ) as ChainV2; -!!!note - Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. ---- END CONTENT --- + const rpc = config.rpcs[chainV1]; + const tokenMap: ChainTokensV2 = {}; -Doc-Content: https://wormhole.com/docs/build/reference/ ---- BEGIN CONTENT --- ---- -title: Reference -description: Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -categories: Reference ---- + for (const token of config.tokensArr) { + const nativeChainV2 = config.sdkConverter.toChainV2(token.nativeChain); -# Reference + const tokenV2: Partial = { + key: token.key, + chain: chainV2, + symbol: token.symbol, + }; -## Get Started + if (nativeChainV2 == chainV2) { + const decimals = + token.decimals[chainContextV1] ?? token.decimals.default; + if (!decimals) { + continue; + } else { + tokenV2.decimals = decimals; + } + const address = config.sdkConverter.getNativeTokenAddressV2(token); + if (!address) throw new Error('Token must have address'); + tokenV2.address = address; + } else { + tokenV2.original = nativeChainV2; + if (token.foreignAssets) { + const fa = token.foreignAssets[chainV1]!; -In this section, you'll find reference information that is essential for development. This includes Wormhole chain IDs, canonical contract addresses, and finality levels for Guardians for each of the supported blockchains in the Wormhole ecosystem. + if (!fa) { + continue; + } else { + tokenV2.address = fa.address; + tokenV2.decimals = fa.decimals; + } + } else { + continue; + } + } -
+ tokenMap[token.key] = tokenV2 as TokenV2; + } -- :octicons-list-ordered-16:{ .lg .middle } **Chain IDs** + v2Config.chains![chainV2] = { rpc, tokenMap }; + } - --- + return await getWormholeV2( + config.v2Network, + [evm, solana, aptos, cosmwasm, sui, algorand], + v2Config + ); +} - Find a mapping of Wormhole chain IDs to the names and network IDs of the supported blockchains. +// setConfig can be called afterwards to override the default config with integrator-provided config +export function setConfig(customConfig?: WormholeConnectConfig) { + const newConfig: InternalConfig = buildConfig(customConfig); - [:custom-arrow: View list of chain IDs](/docs/build/reference/chain-ids/) + // We overwrite keys in the existing object so the references to the config + // imported elsewhere point to the new values + for (const key in newConfig) { + /* @ts-ignore */ + config[key] = newConfig[key]; + } +} -- :material-timer-sand:{ .lg .middle } **Wormhole Finality** +// TODO: add config validation step to buildConfig +//validateConfigs(); + + ``` - --- +### Custom Networks and RPC Endpoints {: #custom-networks-and-rpc-endpoints } - See the levels of finality (consistency) a transaction should meet before being signed by a Guardian for each network. +Specify supported networks, tokens, and custom RPC endpoints. Your users may encounter rate limits using public RPC endpoints if you don't provide your own. - [:custom-arrow: View list of finality levels](/docs/build/reference/consistency-levels/) +=== "Mainnet" -- :octicons-file-code-16:{ .lg .middle } **Contract Addresses** + ```js + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; - --- +const config: WormholeConnectConfig = { + env: 'mainnet', + networks: ['ethereum', 'polygon', 'solana'], + tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], + rpcs: { + ethereum: 'https://rpc.ankr.com/eth', + solana: 'https://rpc.ankr.com/solana', + }, +}; - Discover the contract addresses for Wormhole-deployed contracts on each of the supported blockchains. +function App() { + return ; +} + ``` - This includes the following protocol contracts: +=== "Testnet" - - Core Contract - - Token Bridge - - NFT Bridge - - Wormhole relayer - - CCTP + ```js + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; - [:custom-arrow: View list of contract addresses](/docs/build/reference/contract-addresses/) +const config: WormholeConnectConfig = { + env: 'testnet', + networks: ['sepolia', 'arbitrum_sepolia', 'base_sepolia', 'fuji'], -- :octicons-checkbox-16:{ .lg .middle } **Wormhole Formatted Addresses** + rpcs: { + fuji: 'https://rpc.ankr.com/avalanche_fuji', + base_sepolia: 'https://base-sepolia-rpc.publicnode.com', + }, +}; - --- +function App() { + return ; +} + ``` - Learn how Wormhole formats addresses into a 32-byte hex format for cross-chain compatibility. - - This includes converting addresses between their native formats and the Wormhole format across multiple blockchains. +!!! note + For a complete list of testnet chain names that can be manually added, see the [Testnet Chains List](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/fa4ba4bc349a7caada809f209090d79a3c5962fe/tokenRegistry/src/scripts/importConnect.ts#L44-L55){target=\_blank}. - [:custom-arrow: View details on Wormhole formatted addresses](/docs/build/reference/wormhole-formatted-addresses/) +### Fully Customized Theme {: #fully-customized-theme } -
---- END CONTENT --- +Wormhole Connect offers a high level of customizability that suits and integrates with your application's design, including various options for buttons, backgrounds, popovers, fonts, and more. The following example demonstrates a variety of appearance customizations. Remember, if you prefer a visual to aid in designing your widget, you can use the [no code style interface](https://connect-in-style.wormhole.com/){target=\_blank}. -Doc-Content: https://wormhole.com/docs/build/reference/wormhole-formatted-addresses/ ---- BEGIN CONTENT --- ---- -title: Wormhole Formatted Addresses -description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -categories: Reference ---- +```jsx +import WormholeConnect, { + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; +import red from '@mui/material/colors/red'; +import lightblue from '@mui/material/colors/lightBlue'; +import grey from '@mui/material/colors/grey'; +import green from '@mui/material/colors/green'; +import orange from '@mui/material/colors/orange'; -# Wormhole Formatted Addresses +const customTheme: WormholeConnectTheme = { + mode: 'dark', + primary: grey, + secondary: grey, + divider: 'rgba(255, 255, 255, 0.2)', + background: { + default: '#232323', + }, + text: { + primary: '#ffffff', + secondary: grey[500], + }, + error: red, + info: lightblue, + success: green, + warning: orange, + button: { + primary: 'rgba(255, 255, 255, 0.2)', + primaryText: '#ffffff', + disabled: 'rgba(255, 255, 255, 0.1)', + disabledText: 'rgba(255, 255, 255, 0.4)', + action: orange[300], + actionText: '#000000', + hover: 'rgba(255, 255, 255, 0.7)', + }, + options: { + hover: '#474747', + select: '#5b5b5b', + }, + card: { + background: '#333333', + secondary: '#474747', + elevation: 'none', + }, + popover: { + background: '#1b2033', + secondary: 'rgba(255, 255, 255, 0.5)', + elevation: 'none', + }, + modal: { + background: '#474747', + }, + font: { + primary: 'Impact', + header: 'Impact', + }, +}; -## Introduction +export default function App() { + return ; +} +``` -Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. +### Environment {: #environment } -This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. +You can configure Connect to be used in Testnet environments, too. You can toggle between Mainnet and Testnet environments by defining the `WormholeConnectConfig` as follows: -## Platform-Specific Address Formats +=== "Mainnet" -Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. + ```ts + const config: WormholeConnectConfig = { + env: 'mainnet', + }; + ``` -Here’s an overview of the native address formats and how they are normalized to the Wormhole format: +=== "Testnet" -| Platform | Native Address Format | Wormhole Formatted Address | -|-----------------|----------------------------------|----------------------------| -| EVM | Hex (e.g., 0x...) | 32-byte Hex | -| Solana | Base58 | 32-byte Hex | -| CosmWasm | Bech32 | 32-byte Hex | -| Algorand | Algorand App ID | 32-byte Hex | -| Sui | Hex | 32-byte Hex | -| Aptos | Hex | 32-byte Hex | -| Near | SHA-256 | 32-byte Hex | + ```ts + const config: WormholeConnectConfig = { + env: 'testnet', + }; + ``` +### Custom RPC Endpoint {: #custom-rpc-endpoint } -These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. +You can define a custom RPC provider for your Connect widget to use. This can be especially helpful if you'd like to replace public endpoints with dedicated or private endpoints. -### Address Format Handling +```ts +const config: WormholeConnectConfig = { + rpcs: { + solana: 'https://rpc.ankr.com/solana/ee827255553bb0fa9e0aaeab27e988707e60ea06ae36be0658b778072e94979e', + }, +}; +``` -The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: +### Arbitrary Token {: #arbitrary-token } -```typescript -const platformAddressFormatEntries = [ - ['Evm', 'hex'], - ['Solana', 'base58'], - ['Cosmwasm', 'bech32'], - ['Algorand', 'algorandAppId'], - ['Sui', 'hex'], - ['Aptos', 'hex'], - ['Near', 'sha256'], -]; -``` +The following section shows how to add an arbitrary token to your deployment of Connect. -These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. +!!! note + You will need to [register](https://portalbridge.com/advanced-tools/#/register){target=\_blank} your token with the Token Bridge to get the contract addresses necessary for it to work with Connect. -## Universal Address Methods +This example configuration limits Connect to the Solana and Ethereum networks and a handful of tokens, including `BSKT`, which isn't built in by default and provided under the `tokensConfig` key. -The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. +See [`src/config/types.ts`](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. -Key functions: +```json +const config: WormholeConnectConfig = { + networks: ['solana', 'ethereum'], + tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC', 'BSKT'], + tokensConfig: { + BSKT: { + key: 'BSKT', + symbol: 'BSKT', + nativeChain: 'solana', + tokenId: { + chain: 'solana', + address: '6gnCPhXtLnUD76HjQuSYPENLSZdG8RvDB1pTLM5aLSJA', + }, + coinGeckoId: 'basket', + icon: 'https://assets.coingecko.com/coins/images/34661/standard/BSKT_Logo.png?1705636891', + color: '#2894EE', + decimals: { + default: 5, + }, + }, + }, +}; +``` - - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format +## More Configuration Options {: #more-configuration-options } - ```typescript - const universalAddress = new UniversalAddress('0x123...', 'hex'); - ``` +### Whitelisting Tokens {: #whitelisting-tokens } - - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address +By default, Connect will offer its complete built-in list of assets, but you can restrict the displayed assets by defining a subset of tokens under `tokens`. The default full list is as follows: - ```typescript - const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); - const universalAddress = ethAddress.toUniversalAddress().toString(); - ``` +| Mainnet | Testnet | +|:--------------:|:----------------------------------:| +| ETH | ETH, ETHsepolia | +| WETH | WETH, WETHsepolia | +| USDCeth | USDCeth | +| WBTC | - | +| USDT | - | +| DAI | - | +| BUSD | - | +| MATIC | MATIC | +| WMATIC | WMATIC | +| USDCpolygon | - | +| BNB | BNB | +| WBNB | WBNB | +| USDCbnb | - | +| AVAX | AVAX | +| WAVAX | WAVAX | +| USDCavax | USDCavax | +| FTM | FTM | +| WFTM | WFTM | +| CELO | CELO | +| GLMR | GLMR | +| WGLMR | WGLMR | +| SOL | WSOL | +| PYTH | - | +| SUI | SUI | +| USDCsol | - | +| APT | APT | +| ETHarbitrum | ETHarbitrum, ETHarbitrum_sepolia | +| WETHarbitrum | WETHarbitrum, WETHarbitrum_sepolia | +| USDCarbitrum | USDCarbitrum | +| ETHoptimism | ETHoptimism, ETHoptimism_sepolia | +| WETHoptimism | WETHoptimism, WETHoptimism_sepolia | +| USDCoptimism | USDCoptimism | +| ETHbase | ETHbase, ETHbase_sepolia | +| WETHbase | WETHbase, WETHbase_sepolia | +| tBTC | tBTC | +| tBTCpolygon | tBTCpolygon | +| tBTCoptimism | tBTCoptimism | +| tBTCarbitrum | tBTCarbitrum | +| tBTCbase | tBTCbase | +| tBTCsol | tBTCsol | +| WETHpolygon | - | +| WETHbsc | - | +| wstETH | wstETH | +| wstETHarbitrum | - | +| wstETHoptimism | - | +| wstETHpolygon | - | +| wstETHbase | - | - - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform +### Routes {: #routes } - ```typescript - const nativeAddress = universalAddress.toNative('Evm'); - ``` +By default, Connect will offer its complete built-in list of routes, but you can restrict the possible route assets by defining a subset under `routes.` By default, Connect will offer its complete built-in list: - - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations +| Mainnet | Testnet | +|:------------:|:----------:| +| bridge | bridge | +| relay | relay | +| cctpManual | cctpManual | +| cctpRelay | cctpRelay | +| nttManual | nttManual | +| nttRelay | nttRelay | +| ethBridge | - | +| wstETHBridge | - | +| usdtBridge | - | +| tBTC | tBTC | - ```typescript - console.log(universalAddress.toString()); - ``` +### Wallet Set Up {: #wallet-connect-project-id } -These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. +When using Wormhole Connect, your selected blockchain network determines the available wallet options. -## Convert Between Native and Wormhole Formatted Addresses + - For EVM chains, wallets like MetaMask and WalletConnect are supported + - For Solana, you'll see options such as Phantom, Torus, and Coin98 -The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. +The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. -### Convert a Native Address to a Wormhole Formatted Address +If you would like to offer WalletConnect as a supported wallet option, you'll need to obtain a project ID on the [WalletConnect cloud dashboard](https://cloud.walletconnect.com/){target=\_blank}. -Example conversions for EVM and Solana: +### Toggle Hamburger Menu {: #toggle-hamburger-menu } -=== "EVM" +By setting the `showHamburgerMenu` option to **false**, you can deactivate the hamburger menu, causing the links to be positioned at the bottom. - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +#### Add Extra Menu Entry {: #add-extra-menu-entry } -const ethAddress: NativeAddress<'Evm'> = toNative( - 'Ethereum', - '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' -); -const universalAddress = ethAddress.toUniversalAddress().toString(); -console.log('Universal Address (EVM):', universalAddress); - ``` +By setting the `showHamburgerMenu` option to `false,` you can add extra links. The following properties are accessed through the `menu[]` property (e.g., `menu[].label`): -=== "Solana" +| Property | Description | +|:--------:|:-------------------------------------------:| +| `label` | Link name to show up | +| `href` | Target URL or URN | +| `target` | Anchor standard target, by default `_blank` | +| `order` | Order where the new item should be injected | - ```typescript - import { toNative } from '@wormhole-foundation/sdk-core'; +#### Sample Configuration {: #sample-configuration } -const solAddress: NativeAddress<'Solana'> = toNative( - 'Solana', - '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' -); -const universalAddressSol = solAddress.toUniversalAddress().toString(); -console.log('Universal Address (Solana):', universalAddressSol); - ``` - -The result is a standardized address format that is ready for cross-chain operations. - -### Convert Back to Native Addresses - -Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: +```json +{ + "showHamburgerMenu": false, + "menu": [ + { + "label": "Advance Tools", + "href": "https://portalbridge.com", + "target": "_self", + "order": 1 + } + ] +} +``` -```typescript -const nativeAddressEvm = universalAddress.toNative('Evm'); -console.log('EVM Native Address:', nativeAddressEvm); +### CoinGecko API Key {: #coingecko-api-key } -const nativeAddressSolana = universalAddress.toNative('Solana'); -console.log('Solana Native Address:', nativeAddressSolana); -``` +The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. -These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. +### More Networks {: #more-networks } -## Use Cases for Wormhole Formatted Addresses +Specify a set of extra networks to be displayed on the network selection modal, each linking to a different page, dApp, or mobile app the user will be redirected to. The following properties are accessed through the `moreNetworks` property (e.g., `moreNetworks.href`): -### Cross-chain Token Transfers +|
Property
| Description | +|:--------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------:| +| `href` | **Required**. Default value for missing network hrefs | +| `target` | Default value for missing network link targets. Defaults to `_self` | +| `description` | Brief description that should be displayed as a tooltip when the user hovers over a more network icon. Used as default for missing network descriptions | +| `networks[].icon` | **Required**. URL data encoded icon to display | +| `networks[].href` | Network href to redirect to. If present, the values `sourceChain` and `targetChain` are replaced with the currently selected chains before redirecting | +| `networks[].label` | **Required**. Display text | +| `networks[].name` | Unique network key. Defaults to a snake_case version of the label | +| `networks[].description` | Description value. Defaults to `moreNetworks.description` | +| `networks[].target` | href target value. Defaults to `moreNetworks.target` | +| `networks[].showOpenInNewIcon` | Disable top right open in new icon. Defaults to **true** if target is `_blank` or **false** if target is `_self` | -Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. +??? code "View full configuration" + ```json + { + ... + "moreNetworks": { + "href": "https://example.com", + "target": "_blank", + "description": "brief description that should be displayed as tooltip when the user hovers over a more network icon", + "networks": [ + { + "icon": "https://assets.coingecko.com/coins/images/34661/standard/BSKT_Logo.png?1705636891", + "name": "more", + "label": "More networks", + "href": "https://portalbridge.com/#/transfer", + "showOpenInNewIcon": false + } + ] + } + ... +} + ``` -### Smart Contract Interactions +### More Tokens {: #more-tokens } -In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. +Show a particular entry on the select tokens modal, redirecting the user to a different page, dApp, or mobile app. The following properties are accessed through the `moreTokens` property (e.g., `moreTokens.label`): -### DApp Development +| Property | Description | +|:--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------:| +| `label` | **Required**. Display text | +| `href` | **Required**. URL to redirect to. If present, the values `sourceChain` and `targetChain` are replaced with the currently selected chains before redirecting | +| `target` | href target. Defaults to `_self` | -For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. +### Explorer {: #explorer } -### Relayers and Infrastructure +Enable the explorer button to allow users to search for their transactions on a given explorer, filtering by their wallet address. The following properties are accessed through the `explorer` property (e.g., `explorer.label`): -Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +| Property | Description | +|:--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| `label` | Display text. Defaults to `Transactions` | +| `href` | **Required**. URL of the explorer, for instance [https://wormholescan.io/](https://wormholescan.io/){target=\_blank}. If present, the value `address` is replaced with the connected wallet address | +| `target` | `href` target. Defaults to `_blank` | --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/data/ --- BEGIN CONTENT --- --- -title: Start Building -description: This section has all you need to start developing with Wormhole, including a guide to supported networks, tool sets, and code examples. +title: Connect Data Configuration +description: Configure Wormhole Connect v1 (latest) with custom chains, tokens, routes, and more for enhanced blockchain interoperability. +categories: Connect, Transfer --- -# Start Building +## Data Configuration -Wormhole's role as a Generic Message Passing (GMP) protocol means it facilitates interoperability across multiple areas of project development. The following sections will help you locate the tools most relevant to your development needs whether you are focused on building frontend user interfaces or smart contracts and protocols. This section also links to developer resources like references and code examples which are helpful for all builders looking to integrate with Wormhole. +This page explains how to configure Wormhole Connect's core functionality, from choosing supported chains and tokens to bridging routes to setting up wallets and enabling price lookups. By the end, you'll know how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. -## Get Hands-On +## Get Started -
+Configure Wormhole Connect by passing a `WormholeConnectConfig` object as the `config` prop. -- :octicons-repo-16:{ .lg .middle } **Tutorials** +=== "React integration" - --- + ```ts + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; - Follow in-depth, step-by-step tutorials to learn how to build cross-chain contracts, integrate Wormhole's SDK, and more. +const config: WormholeConnectConfig = { + chains: ['Ethereum', 'Polygon', 'Solana'], + tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], + rpcs: { + Ethereum: 'https://rpc.ankr.com/eth', + Solana: 'https://rpc.ankr.com/solana', + } +} - [:custom-arrow: Explore tutorials](/docs/tutorials/) + + ``` -
+=== "Hosted integration" -## Essential Resources for Development + ```ts + import WormholeConnect, { + wormholeConnectHosted, + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -
+const config: WormholeConnectConfig = { + chains: ['Ethereum', 'Polygon', 'Solana'], + tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], + rpcs: { + Ethereum: 'https://rpc.ankr.com/eth', + Solana: 'https://rpc.ankr.com/solana', + }, +}; -- :octicons-broadcast-16:{ .lg .middle } **Supported Networks** +const container = document.getElementById('bridge-container'); - --- +wormholeConnectHosted(container, { + config, +}); + ``` - Explore the blockchains supported by Wormhole for cross-chain communication and asset transfers. Understand which networks are available for both Testnet and Mainnet environments. +!!! note + The complete type definition of `WormholeConnectConfig` is available in the [Wormhole Connect repository](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank}. - [:custom-arrow: Discover supported networks](/docs/build/start-building/supported-networks/) +## Examples {: #examples } -- :octicons-goal-16:{ .lg .middle } **Testnet Faucets** +### Configuring Chains and RPC Endpoints {: #chains-and-rpc-endpoints } - --- +Connect lets you customize the available chains to match your project's needs. You should provide your own RPC endpoints, as the default public ones may not support essential functions like balance fetching. - Get Testnet tokens to start experimenting with cross-chain transfers and contract deployment. +=== "Mainnet" - [:custom-arrow: Find Testnet faucets](/docs/build/start-building/testnet-faucets/) + ```js + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -- :octicons-list-unordered-16:{ .lg .middle } **Reference** +const config: WormholeConnectConfig = { + chains: ['Ethereum', 'Polygon', 'Solana'], + rpcs: { + Ethereum: 'https://rpc.ankr.com/eth', + Solana: 'https://rpc.ankr.com/solana', + }, +}; - --- +function App() { + return ; +} + ``` - Access the essential Wormhole chain IDs and smart contract addresses for messaging protocols, token bridges, and other key components. +=== "Testnet" - [:custom-arrow: Explore Reference](/docs/build/reference/){target=\_blank} + ```js + import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -
---- END CONTENT --- +const config: WormholeConnectConfig = { + // You can use Connect with testnet chains by specifying "network": + network: 'Testnet', + chains: ['Sepolia', 'ArbitrumSepolia', 'BaseSepolia', 'Avalanche'], + rpcs: { + Avalanche: 'https://rpc.ankr.com/avalanche_fuji', + BaseSepolia: 'https://base-sepolia-rpc.publicnode.com', + }, +}; -Doc-Content: https://wormhole.com/docs/build/start-building/products/ ---- BEGIN CONTENT --- ---- -title: Compare Wormhole's Cross-Chain Solutions -description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -categories: Transfer, Basics ---- +function App() { + return ; +} + ``` -# Products +!!! note + For a complete list of available chain names, see the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank}. -Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. +### Configuring Routes -Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. +By default, Connect offers two bridging protocols: Token Bridge (for Wormhole-wrapped tokens) and Circle's CCTP (for native USDC). For most use cases, integrators require more than these default routes. The `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including default and third-party routes. -Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. +#### Available Route Plugins -## Transfer Products +The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: -Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. +- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank}: Manually redeemed Wormhole Token Bridge route. +- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank}: Automatically redeemed (relayed) Token Bridge route. +- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank}: Manually redeemed CCTP route. +- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank}: Automatically redeemed (relayed) CCTP route. +- **`DEFAULT_ROUTES`**: Array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`). +- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank}: Function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route. +- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}: Function that returns the manually-redeemed NTT route. +- **`nttRoutes(nttConfig)`**: Function that returns both NTT routes as an array. +- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank}: Route that offers multiple Mayan protocols. +- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank}: Route for Mayan's Swift protocol only. +- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank}: Route for Mayan's MCTP protocol only. +- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank}: Route for Mayan's original Wormhole transfer protocol. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +In addition to these routes, developers can create custom routes for their Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. -
+For further details on the `route` plugin interface, refer to the [Wormhole TypeScript SDK route code](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/route.ts){target=\_blank}. -::spantable:: +#### Example: Offer Only CCTP Transfers -| | Criteria | NTT | Token Bridge | Settlement | -|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| -| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | -| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | -| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | -| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | -| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | -| | Intent-Based Execution | :x: | :x: | :white_check_mark: | -| | Fast Settlement | :x: | :x: | :white_check_mark: | -| | Liquidity Optimization | :x: | :x: | :white_check_mark: | -| Integration Details @span | | | | | -| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | -| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | -| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | +To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: -::end-spantable:: +```typescript +import WormholeConnect, { + AutomaticCCTPRoute, + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -
+const config: WormholeConnectConfig = { + routes: [AutomaticCCTPRoute], +}; -Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. +; +``` -## Bridging UI +#### Example: Offer All Default Routes and Third-Party Plugins -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. -## Real-time Data +```typescript +import WormholeConnect, { + DEFAULT_ROUTES, + nttRoutes, + MayanRouteSWIFT, + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +import { myNttConfig } from './consts'; // Custom NTT configuration -## Multichain Governance +const config: WormholeConnectConfig = { + routes: [...DEFAULT_ROUTES, ...nttRoutes(myNttConfig), MayanRouteSWIFT], +}; -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. ---- END CONTENT --- +; +``` -Doc-Content: https://wormhole.com/docs/build/start-building/supported-networks/ ---- BEGIN CONTENT --- ---- -title: Supported Networks -description: Learn about the networks each Wormhole product supports, and explore links to documentation, official websites, and block explorers. -categories: Reference ---- +This flexible plugin allows you to combine default routes (such as Token Bridge and CCTP) with third-party protocols, offering complete control over which routes are available in your application. -# Supported Networks +### Adding Custom Tokens {: #custom-tokens } -Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. +The following section shows how to add an arbitrary token to your deployment of Connect. -## Networks +!!! note + You will need to [register](https://portalbridge.com/advanced-tools/#/register){target=\_blank} your token with the Token Bridge to get the contract addresses necessary for it to work with that protocol. - - -
+This example configuration adds the BONK token to Connect. Note the `wrappedTokens` property, which is required for use with the Token Bridge. -### Connect +See the [Connect source code](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. -| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Solana | SVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Aptos | Move VM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Berachain | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Osmosis | CosmWasm | :x: | :x: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sui | Sui Move VM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
- - -
+```typescript +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -### NTT +const config: WormholeConnectConfig = { + tokensConfig: { + BONK: { + key: 'BONK', + symbol: 'BONK', + nativeChain: 'Ethereum', + icon: Icon.ETH, + tokenId: { + chain: 'Ethereum', + address: '0x1151CB3d861920e07a38e03eEAd12C32178567F6', + }, + coinGeckoId: 'bonk', + decimals: 18, + }, + }, + wrappedTokens: { + BONK: { + Solana: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', + }, + }, +}; +``` -| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Berachain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Gnosis | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| HyperEVM | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs | -| Ink | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Kaia | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Linea | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Monad | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Neon | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Seievm | EVM | :white_check_mark: | :white_check_mark: | :x: | | -| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
- - -
+### Whitelisting Tokens {: #whitelisting-tokens } -### Token Bridge +Connect offers a list of built-in tokens by default. You can see it below: -| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Algorand | AVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Aptos | Move VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Berachain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| HyperEVM | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs | -| Injective | CosmWasm | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Ink | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Kaia | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Linea | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Monad | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| NEAR | NEAR VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Neon | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sei | CosmWasm | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Seievm | EVM | :white_check_mark: | :white_check_mark: | :x: | | -| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sui | Sui Move VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Terra 2.0 | CosmWasm | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
- - -
+- [Mainnet tokens](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/mainnet/tokens.ts){target=\_blank} +- [Testnet tokens](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/testnet/tokens.ts){target=\_blank} -### CCTP +You can customize the tokens shown in the UI using the `tokens` property. The following example adds a custom token and limits Connect to showing only that token, along with the native gas tokens ETH and SOL. -| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
- - -
+```jsx +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -### Settlement +const config: WormholeConnectConfig = { + chains: ['Ethereum', 'Solana'], + tokens: ['ETH', 'SOL', 'BONK'], + rpcs: { + Ethereum: 'https://rpc.ankr.com/eth', + Solana: 'https://rpc.ankr.com/solana', + }, + tokensConfig: { + BONK: { + key: 'BONK', + symbol: 'BONK', + icon: 'https://assets.coingecko.com/coins/images/28600/large/bonk.jpg?1696527587', + tokenId: { + chain: 'Ethereum', + address: '0x1151CB3d861920e07a38e03eEAd12C32178567F6', + }, + decimals: 18, + }, + }, + wrappedTokens: { + BONK: { + Solana: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', + }, + }, +}; -| Ethereum | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Solana | SVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sui | Sui Move VM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Unichain | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
- - -
+function App() { + return ; +} +``` -### MultiGov +You can whitelist tokens by symbol or by specifying tuples of [chain, address]. For example, this would show only BONK token (on all chains you've whitelisted) as well as [`EPjFW...TDt1v`](https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v){target=\_blank} on Solana, which is USDC. -| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Base | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Berachain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Blast | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Celo | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Fantom | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Gnosis | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| HyperEVM | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs | -| Ink | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Kaia | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Linea | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mantle | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Mezo | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Monad | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Neon | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Optimism | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Polygon | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Scroll | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sei | CosmWasm | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Seievm | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Sonic | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| Unichain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| World Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -| X Layer | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | -
---- END CONTENT --- +```jsx +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -Doc-Content: https://wormhole.com/docs/build/start-building/testnet-faucets/ ---- BEGIN CONTENT --- ---- -title: Testnet Faucets -description: This page includes resources to quickly find the Testnet tokens you need to deploy and test applications and contracts on Wormhole's supported networks. -categories: Reference ---- +const config: WormholeConnectConfig = { + chains: ['Ethereum', 'Solana'], + tokens: [ + // Whitelist BONK on every whitelisted chain + 'BONK', + // Also whitelist USDC, specifically on Solana + ['Solana', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'] + ], + ... +}; -# Testnet Faucets +function App() { + return ; +} +``` -## Get Started +### User-Inputted Tokens {: #user-inputted-tokens } -Don't let the need for testnet tokens get in the way of buildling your next great idea with Wormhole. Use this guide to quickly locate the testnet token faucets you need to deploy and test applications and contracts on Wormhole's supported networks. +As of version 2.0, Connect allows users to paste token addresses to bridge any token they want. As an integrator, you may want to disable this feature if you are deploying Connect for use only with a specific token(s). - - -
+If you provide a token whitelist (see above), this is turned off automatically. However, you can also disable it explicitly like this: -### EVM +```jsx +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -| Ethereum Holesky | EVM | ETH | Alchemy Faucet | -| Ethereum Sepolia | EVM | ETH | Alchemy Faucet | -| Arbitrum Sepolia | EVM | ETH | List of Faucets | -| Avalanche | EVM | AVAX | Official Avalanche Faucet | -| Base Sepolia | EVM | ETH | List of Faucets | -| Berachain | EVM | BERA | Official Berachain Faucet | -| Blast | EVM | ETH | List of Faucets | -| BNB Smart Chain | EVM | BNB | Official BNB Faucet | -| Celo | EVM | CELO | Official Celo Faucet | -| Fantom | EVM | FTM | Official Fantom Faucet | -| Gnosis | EVM | xDAI | Official Gnosis Faucet | -| HyperEVM | EVM | mock USDC | Official Hyperliquid Faucet | -| Ink | EVM | ETH | Official Ink Faucet | -| Kaia | EVM | KAIA | Official Kaia Faucet | -| Linea | EVM | ETH | List of Faucets | -| Mantle | EVM | MNT | Official Mantle Faucet | -| Monad | EVM | MON | Official Monad Faucet | -| Moonbeam | EVM | DEV | Official Moonbeam Faucet | -| Neon | EVM | NEON | Official Neon Faucet | -| Optimism Sepolia | EVM | ETH | Superchain Faucet | -| Polygon Amoy | EVM | POL | Official Polygon Faucet | -| Scroll | EVM | ETH | List of Faucets | -| Unichain | EVM | ETH | QuickNode Faucet | -| World Chain | EVM | ETH | Alchemy Faucet | -| X Layer | EVM | OKB | X Layer Official Faucet | +const config: WormholeConnectConfig = { + ui: { + disableUserInputtedTokens: true + } +}; -### SVM +function App() { + return ; +} +``` -| Pythnet | SVM | ETH | Superchain Faucet | +Setting `ui.disableUserInputtedTokens` to `true` will disable the ability to paste in token addresses. -### AVM +### Transaction Settings {: #transaction-settings } -| Algorand | AVM | ALGO | Official Algorand Faucet | +Landing transactions on Solana can require finely tuned priority fees when there is congestion. You can tweak how Connect determines these with `transactionSettings`. All of the parameters in this configuration are optional; you can provide any combination of them. -### CosmWasm +```jsx +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -| Celestia | CosmWasm | TIA | Discord Faucet | -| Cosmos Hub | CosmWasm | ATOM | Discord Faucet | -| Evmos | CosmWasm | TEVMOS | Official Evmos Faucet | -| Injective | CosmWasm | INJ | Official Injective Faucet | -| Kujira | CosmWasm | KUJI | Discord Faucet | -| Neutron | CosmWasm | NTRN | List of Faucets | -| Noble | CosmWasm | USDC | Circle Faucet | -| Osmosis | CosmWasm | OSMO | Official Osmosis Faucet | -| SEDA | CosmWasm | SEDA | Official SEDA Faucet | -| Sei | CosmWasm | SEI | Sei Atlantic-2 Faucet | -| Terra 2.0 | CosmWasm | LUNA | Terra Official Faucet | +const config: WormholeConnectConfig = { + transactionSettings: { + Solana: { + priorityFee: { + // Number between 0-1, defaults to 0.9. Higher percentile yields higher fees. + // For example, you can set percentile to 0.95 to make Connect compute the + // 95th percentile priority fee amount based on recent transactions + percentile: 0.95, -### Move VM + // Any number, defaults to 1.0. The fee amount is multiplied by this number. + // This can be used to further raise or lower the fees Connect is using. + // For example, percentile=0.95 and percentileMultiple=1.1 would use + // the 95th percentile fee, with a 10% increase + percentileMultiple: 1.1, -| Aptos | Move VM | APT | Official Aptos Faucet | + // Minimum fee you want to use in microlamports, regardless of recent transactions + // Defaults to 1 + min: 200_000, -### NEAR VM + // Maximum fee you want to use in microlamports, regardless of recent transactions + // Defaults to 100,000,000 + max: 5_000_000, + } + } + } +}; -| NEAR | NEAR VM | NEAR | Official NEAR Faucet | +function App() { + return ; +} +``` -### Sui Move VM +!!! note + Connect can calculate fees more accurately if you are using a [Triton](https://triton.one){target=\_blank} RPC endpoint. -| Sui | Sui Move VM | SUI | List of Faucets | -
- +### Wallet Set Up {: #reown-cloud-project-id } + +Your selected blockchain network determines the available wallet options when using Wormhole Connect. + + - For EVM chains, wallets like MetaMask and Reown Cloud (formerly WalletConnect) are supported + - For Solana, you'll see options such as Phantom, Torus, and Coin98 + +The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. + +If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/start-building/use-cases/ +Doc-Content: https://wormhole.com/docs/products/connect/configuration/theme/ --- BEGIN CONTENT --- --- -title: Use Cases -description: Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -categories: Basics +title: Connect Theme & UI Customization +description: Learn how to style Wormhole Connect with custom color schemes, fonts, layouts, and menus for a streamlined user experience. +categories: Connect, Transfer --- -# Wormhole Use Cases +## Theme & UI Customization -
-
+This page focuses on how to style the Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. -## Cross-Chain Swaps and Liquidity Aggregation +### Changing the Color Scheme -Enable seamless swaps between chains with real-time liquidity routing. +You can customize Connect's color scheme by providing a `theme` prop. -
-
+=== "React integration" -🛠 **Wormhole products used:** + ```ts + import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – handles user-friendly asset transfers -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – moves native assets across chains -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time prices for optimal trade execution +const config: WormholeConnectConfig = { + /* Your config... */ +}; -🔗 **Used in:** Decentralized exchanges (DEXs) and liquidity aggregators
🏗️ **Used by:** [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank} +const theme: WormholeConnectTheme = { + mode: 'dark', + primary: '#78c4b6', + font: 'Comic Sans; sans-serif', +}; -
-
+function App() { + return ; +} + ``` +=== "Hosted integration" -
-
+ ```ts + import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, + wormholeConnectHosted, +} from '@wormhole-foundation/wormhole-connect'; -## Borrowing and Lending Across Chains +const config: WormholeConnectConfig = { + /* Your config... */ +}; -Let users borrow assets on one chain using collateral from another. +const theme: WormholeConnectTheme = { + mode: 'dark', + primary: '#78c4b6', + font: 'Comic Sans; sans-serif', +}; -
-
+const container = document.getElementById('bridge-container'); -🛠 **Wormhole products used:** +wormholeConnectHosted(container, { + config, + theme, +}); + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves loan requests and liquidations across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers collateral as native assets -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches interest rates and asset prices in real-time +The `WormholeConnectTheme` type supports the following properties: -🔗 **Used in:** Lending protocols and yield platforms
🏗️ **Used by:** [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank} +|
Property
| Description | Example | +|:--------------------------------------:|:---------------------------------------------------------------------:|:---------------------:| +| `mode` | Dark mode or light mode. **Required** | `"dark"` or `"light"` | +| `input` | Color used for input fields, dropdowns | `"#AABBCC"` | +| `primary` | Primary color used for buttons | `"#AABBCC"` | +| `secondary` | Secondary color used for some UI elements | `"#AABBCC"` | +| `text` | Primary color used for text | `"#AABBCC"` | +| `textSecondary` | Secondary color used for dimmer text | `"#AABBCC"` | +| `error` | Color to display errors in, usually some shade of red | `"#AABBCC"` | +| `success` | Color to display success messages in | `"#AABBCC"` | +| `font` | Font used in the UI, can be custom font available in your application | `"Arial; sans-serif"` | -
-
+### Toggle Hamburger Menu {: #toggle-hamburger-menu } +By setting the `showHamburgerMenu` option to **false**, you can deactivate the hamburger menu, which will position the links at the bottom. -
-
+#### Add Extra Menu Entry {: #add-extra-menu-entry } -## Real-Time Price Feeds and Trading Strategies +By setting the `showHamburgerMenu` option to `false,` you can add extra links. The following properties are accessed through the `menu[]` property (e.g., `menu[].label`): -Fetch price feeds across multiple chains for DeFi applications. +| Property | Description | +|:--------:|:-------------------------------------------:| +| `label` | Link name to show up | +| `href` | Target URL or URN | +| `target` | Anchor standard target, by default `_blank` | +| `order` | Order where the new item should be injected | -
-
+```jsx +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -🛠 **Wormhole products used:** +const config: WormholeConnectConfig = { + ui: { + showHamburgerMenu: false, + menu: [ + { + label: 'Advance Tools', + href: 'https://portalbridge.com', + target: '_self', + order: 1, + }, + ], + }, +}; -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches price feeds from oracles and trading platforms -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – sends signals to execute trades +function App() { + return ; +} +``` +--- END CONTENT --- -🔗 **Used in:** Trading bots, arbitrage platforms, and oracles
🏗️ **Used by:** [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank} +Doc-Content: https://wormhole.com/docs/products/connect/faqs/ +--- BEGIN CONTENT --- +--- +title: Connect FAQs +description: Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. +categories: Connect, Transfer +--- -
-
+# Wormhole Connect FAQs +## What types of assets does Connect support? -
-
+Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: -## Asset Movement Between Bitcoin and Other Chains + - Major stablecoins like USDT and USDC (via CCTP) + - Native gas tokens such as ETH, SOL, etc. + - Cross-chain asset swaps through integrators like Mayan -Enable direct BTC transfers without wrapped assets. +When bridging assets through the Wormhole Token Bridge, depending on the chain and token, assets may arrive as Wormhole-wrapped tokens on the destination chain. -
-
+## What chains does Connect support? -🛠 **Wormhole products used:** +Connect supports around 30 chains, spanning various blockchain runtimes: -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers BTC across chains + - EVM-based chains (Ethereum, Base, Arbitrum, BSC, etc.) + - Solana + - Move-based chains (Sui, Aptos) -🔗 **Used in:** Bitcoin DeFi and lightning network integrations
🏗️ **Used by:** [Synonym](https://wormhole.com/case-studies/synonym){target=\_blank} +For a complete list of supported chains, see the [Connect-supported chains list](/docs/products/connect/reference/support-matrix/){target=\_blank}. -
-
+## What is gas dropoff? -
-
+Gas dropoff allows users to receive gas for transaction fees on the destination chain, eliminating the need to acquire the native gas token from a centralized exchange. The relayer automatically swaps part of the transferred assets into the native gas token, enabling seamless entry into new ecosystems. -## Decentralized Social Platforms +## Can I customize Connect inside my application? -Enable seamless communication and asset transfer across decentralized social networks. +Connect can be [fully customized](https://connect-in-style.wormhole.com/){target=\_blank} to choose the chains and assets you wish to support. You may also select different themes and colors to tailor Connect for your decentralized application. For details, see the [GitHub readme](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. -
-
+## Which functions or events does Connect rely on for NTT integration? -🛠 **Wormhole products used:** +Connect relies on the NTT SDK for integration, with platform-specific implementations for Solana and EVM. The critical methods involved include initiate and redeem functions and rate capacity methods. These functions ensure Connect can handle token transfers and manage chain-rate limits. -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates decentralized interactions -- [**Token Bridge**](/docs/build/transfers/token-bridge/){target=\_blank} – enables cross-chain tokenized rewards +## Do integrators need to enable wallets like Phantom or Backpack in Connect? -🔗 **Used in:** Web3 social networks and content monetization
🏗️ **Used by:** [Chingari](https://chingari.io/){target=\_blank} +Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. -
-
+## Which function should be modified to set priority fees for Solana transactions? +In [Wormhole Connect](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}, you can modify the priority fees for Solana transactions by updating the `computeBudget/index.ts` file. This file contains the logic for adjusting the compute unit limit and priority fees associated with Solana transactions. -
-
+To control the priority fee applied to your transactions, you can modify the `feePercentile` and `minPriorityFee` parameters in the `addComputeBudget` and `determineComputeBudget` functions. -## Memecoin Launchpads +The relevant file can be found in the Connect codebase: [`computeBudget/index.ts`](https://github.com/wormhole-foundation/wormhole-connect/blob/62f1ba8ee5502ac6fd405680e6b3816c9aa54325/sdk/src/contexts/solana/utils/computeBudget/index.ts){target=\_blank}. -Launch and distribute memecoins across multiple chains, enabling cross-chain fundraising and liquidity access. +## Is there a minimum amount for bridging with CCTP or the Connect SDK? -
-
- -🛠 **Wormhole products used:** - -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – enables native asset transfers for seamless fundraising -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – facilitates cross-chain token distribution and claim processes - -🔗 **Used in:** Token launchpads, IDOs, and meme token ecosystems +There is no minimum amount for bridging via CCTP if the user covers the gas fees on both the source and destination chains. However, if the transfer is automatically relayed, a minimum amount is required to cover relay fees on the destination chain. The relay provider charges these fees at cost. -
-
+Current relay fees: +- Ethereum L1: ~4.2 USDC +- Base, Optimism, Arbitrum, Avalanche: 0.3 USDC -
-
+Additional notes: -## Cross-Chain Perpetuals +- **USDC to Solana** - Wormhole's native CCTP route does not currently support automatic relaying of USDC to Solana. However, you can transfer USDC to Solana using the [Mayan plugin](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} for the SDK. Mayan is a protocol that integrates Wormhole and CCTP to enable this functionality +- **Frontend integrations** + - **Connect** - A pre-built UI available via [@wormhole-foundation/wormhole-connect](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} + - **TypeScript SDK** - A lower-level integration option, available via [@wormhole-foundation/sdk](https://www.npmjs.com/package/@wormhole-foundation/sdk){target=\_blank}, allowing developers to build custom UIs -Enable leveraged perpetual trading across chains with seamless collateral and liquidity management. + !!!note + The TypeScript SDK was previously referred to as the "Connect SDK," but this naming has since been discontinued. +--- END CONTENT --- -
-
+Doc-Content: https://wormhole.com/docs/products/connect/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Connect +description: Follow this guide to configure and use the Connect UI widget to easily add an intuitive, multichain asset transfer UI to your web applications. +categories: Connect, Transfer +--- -🛠 **Wormhole products used:** +# Get Started with Connect -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time asset prices and manages position state across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - for quick cross-chain token execution, providing efficient and seamless user experiences +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -🔗 **Used in:** Perpetual DEXs, trading platforms and cross-chain derivatives +## Introduction -
-
+Connect helps you to easily add an intuitive, multichain asset transfer UI to your web applications. The guide demonstrates how to configure the Connect widget, add it to a React application, and view it locally. +## Install Connect -
-
+To install the [Wormhole Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: -## Gas Abstraction +```bash +npm i @wormhole-foundation/wormhole-connect +``` -Allow users to pay gas fees with any token across different networks, removing friction in multichain interactions. +## Prerequisites -
-
+Before you begin, make sure you have the following: -🛠 **Wormhole products used:** +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – routes gas fee payments across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – facilitates native token conversion for gas payments +- (Optional) To test a transfer from your demo app, you'll need: -🔗 **Used in:** Wallets, dApps, and multichain user experience improvements + - A wallet with [Sui testnet tokens](https://faucet.sui.io/){target=\_blank} + - A wallet with an Avalanche Fuji address (to use as the recipient; no tokens required) -
-
+## Install and Set Up Project +1. Clone the demo repository and navigate to the project directory: -
-
+ ```bash + git clone https://github.com/wormhole-foundation/demo-basic-connect.git + cd demo-basic-connect + ``` -## Bridging Intent Library +2. Install the dependencies: -Provide developers with a library of bridging intents and automation functions, enabling plug-and-play interoperability logic. + ```bash + npm install + ``` -
-
+3. Start the application: -🛠 **Wormhole products used:** + ```bash + npm start + ``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – enables predefined cross-chain actions and triggers. -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} - provides a framework for executing user-defined bridging intents +4. Open your browser to [localhost:3000](http://localhost:3000){target=\_blank} to view the application locally. It will look similar to the following: -🔗 **Used in:** Bridging protocols, DeFi automation, and smart contract libraries + ![Deployed Connect Widget](/docs/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp) -
-
+## Configure Connect +Open the `App.tsx` file in your code editor of choice. You will see code similar to the following: -
-
+```typescript title="App.tsx" +import './App.css'; +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; -## Multichain Prediction Markets +function App() { + const config: WormholeConnectConfig = { + // Define the network + network: 'Testnet', -Allow users to place bets, manage positions, and receive payouts seamlessly across different networks. + // Define the chains + chains: ['Sui', 'Avalanche'], -
-
+ // UI configuration + ui: { + title: 'SUI Connect TS Demo', + }, + }; -🛠 **Wormhole products used:** + const theme: WormholeConnectTheme = { + // Define the theme + mode: 'dark', + primary: '#78c4b6', + }; -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches real-time market data, tracks collateral, and manages odds across chains -- [**Wormhole Settlement**](/docs/learn/transfers/settlement/overview/){target=\_blank} – automates token execution for efficient and seamless cross-chain prediction market interactions + return ; +} -🔗 **Used in:** Decentralized betting, prediction markets, and cross-chain gaming +export default App; +``` -
-
+The preceding sample code configures Connect by setting values inside `config` and `theme` as follows: +- **Defines the network**: Options include `Mainnet`, `Testnet`, or `Devnet`. +- **Defines chains to include**: This example uses Sui and Avalanche. See the complete list of [Connect-supported chain names](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank} if you would like to use different chains. +- **Adds a title to UI**: (Optional) If defined, it will render above the widget in the UI. +- **Defines the theme**: This example sets the mode to `dark` and adds a primary color. -
-
+## Interact with Connect -## Cross-Chain Payment Widgets +Congratulations! You've successfully used Connect to create a simple multichain token transfer application. You can now follow the prompts in the UI to connect your developer wallets and send a test transfer. -Allow merchants and platforms to accept payments in any token, auto-converting them into a desired asset. +## Next Steps -
-
+Use the following guides to configure your Connect instance and integrate it into your application: -🛠 **Wormhole products used:** +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. +- **[Integrate Connect into a React DApp](/docs/products/connect/tutorials/react-dapp/)**: Learn how to integrate Connect into a React application, including setting up the widget and handling transfers. -- [**Wormhole Connect**](/docs/build/transfers/connect/overview/){target=\_blank} – facilitates seamless payments in various tokens -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – ensures direct, native asset transfers + +--- END CONTENT --- -🔗 **Used in:** E-commerce, Web3 payments, and subscription models +Doc-Content: https://wormhole.com/docs/products/connect/guides/hosted-version/ +--- BEGIN CONTENT --- +--- +title: Integrate Connect via CDN +description: +categories: Connect, Transfer +--- -
-
+# Integrate Connect via CDN +[Wormhole Connect](/docs/products/connect/overview/){target=\_blank} is a prebuilt UI component that makes it easy to transfer tokens across chains. You can integrate it into any website using either React or a hosted version served via [jsDelivr](https://www.jsdelivr.com/){target=\_blank}. -
-
+This guide focuses on using the hosted version—ideal for simpler setups or non-React environments. It includes everything you need to get started with just a few lines of code. -## Oracle Networks +If you're using React, refer to the [Get Started with Connect](/docs/products/connect/get-started/){target=\_blank} guide. -Fetch and verify cross-chain data, enabling reliable, decentralized Oracle services for multichain applications. +## Install Connect -
-
+To install the [Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: -🛠 **Wormhole products used:** +```bash +npm i @wormhole-foundation/wormhole-connect +``` -- [**Queries**](/docs/build/queries/overview/){target=\_blank} – fetches data from multiple chains and Oracle providers -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – ensures tamper-proof data relay across networks +## Add Connect to Your Project Using the Hosted Version -🔗 **Used in:** Price feeds, DeFi protocols, and smart contract automation
🏗️ **Used by:** [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank} +The hosted version uses pre-built packages (including React) served via jsDelivr from npm. To integrate it without using React directly, add the following to your JavaScript project: -
-
+```js +import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; +// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'bridge-container' not found"); +} -
-
+wormholeConnectHosted(container); +``` -## Cross-Chain Staking +You can provide config and theme parameters in a second function argument: -Enable users to stake assets on one chain while earning rewards or securing networks on another. +```js +import { + wormholeConnectHosted, +} from '@wormhole-foundation/wormhole-connect'; -
-
+// Existing DOM element where you want to mount Connect +const container = document.getElementById('bridge-container'); +if (!container) { + throw new Error("Element with id 'connect' not found"); +} -🛠 **Wormhole products used:** +wormholeConnectHosted(container, { + config: { + rpcs: { + // ... + } + }, + theme: { + background: { + default: '#004547', + } + } +}); +``` -- [**Messaging**](/docs/learn/infrastructure/){target=\_blank} – moves staking rewards and governance signals across chains -- [**Native Token Transfer**](/docs/build/transfers/native-token-transfers/){target=\_blank} – transfers staked assets natively between networks +## Next Steps -🔗 **Used in:** Liquid staking, cross-chain governance, and PoS networks
🏗️ **Used by:** [Lido](https://lido.fi/){target=\_blank} +Use the following guides to configure your Connect instance: -
-
+- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/cli/ +Doc-Content: https://wormhole.com/docs/products/connect/guides/upgrade/ --- BEGIN CONTENT --- --- -title: Wormhole CLI -description: Learn how to install and use the Wormhole CLI, including commands and examples for managing multichain deployments, generating VAAs, and querying contract info. -categories: Solidity-SDK, Typescript-SDK +title: Wormhole Connect v1.0 Migration Guide +description: Learn how to migrate to Wormhole Connect v1.0, with step-by-step guidance on updating your package and configuration. +categories: Connect, Transfer --- -# Wormhole CLI +# Wormhole Connect v1.0 Migration Guide -This tool is a command-line interface to Wormhole, allowing you to perform various actions, such as querying a transaction's status or submitting token transfers. +## Overview -## Installation +The Wormhole Connect feature has been updated to **version 1.0**, introducing a modernized design and improved routing for faster native-to-native token transfers. This stable release comes with several breaking changes in how to configure the application, requiring minor updates to your integration. -Clone the repository and change directories to the appropriate directory: +This guide will help you migrate to the new version in just a few simple steps. By following this migration guide, you'll learn how to: -```bash -git clone https://github.com/wormhole-foundation/wormhole && -cd wormhole/clients/js -``` + - Update to the latest Connect package + - Apply configuration changes to the **`WormholeConnectConfig`** object + - Understand new routing capabilities and plugin options -Build and install the CLI tool: +These updates ensure better performance and a smoother integration experience. + +## Update the Connect Package + +To begin the migration process, update the Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. + +Run the following command in your terminal: ```bash -make install +npm install @wormhole-foundation/wormhole-connect@^1.0 ``` -This installs two binaries, `worm-fetch-governance` and `worm` on your `$PATH`. To use `worm`, set up `$HOME/.wormhole/.env` with your private keys, based on `.env.sample` in this folder. +This command installs the latest stable version of Wormhole Connect and prepares your environment for the new configuration changes. -## Usage +## Update the `WormholeConnectConfig` Object -You can interact with the Wormhole CLI by typing `worm` and including the `command` and any necessary subcommands and parameters. +In version 1.0, the `WormholeConnectConfig` object underwent several breaking changes. Most of these changes are minor and can be applied quickly. Below is a summary of the key changes, followed by detailed examples. -| Command | Description | -|--------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| -| `worm aptos INSERT_COMMAND` | Aptos utilities | -| `worm edit-vaa INSERT_COMMAND` | Edits or generates a VAA | -| `worm evm INSERT_COMMAND` | EVM utilities | -| `worm generate INSERT_COMMAND` | Generate VAAs (Devnet and Testnet only) | -| `worm info INSERT_COMMAND` | Contract, chain, RPC, and address information utilities | -| `worm near INSERT_NETWORK, INSERT_ACCOUNT` | NEAR utilities | -| `worm parse INSERT_VAA` | Parse a VAA (can be in either hex or base64 format) | -| `worm recover INSERT_DIGEST INSERT_SIGNATURE` | Recover an address from a signature | -| `worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH` | Prints information about the automatic delivery initiated on the specified network, chain, and transaction hash | -| `worm submit INSERT_VAA` | Execute a VAA | -| `worm sui INSERT_COMMAND` | Sui utilities | -| `worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK` | Transfers a token | -| `worm verify-vaa INSERT_VAA, INSERT_NETWORK` | Verifies a VAA by querying the Core Contract on Ethereum | +### Summary of Breaking Changes -You can also refer to the below options, available with all `worm` commands: +- Chain names are now capitalized: `solana` → `Solana` +- `env` renamed to `network` and is now capitalized: `mainnet` → `Mainnet` +- `networks` renamed to `chains`, with capitalized names +- `routes` updated to use route plugins +- `nttGroups` removed in favor of route plugin configuration +- `tokensConfig` updated, with a new key `wrappedTokens` added +- Many UI-related properties consolidated under a top-level `ui` key +- `customTheme` and `mode` were removed, replaced by a top-level `theme` property -```bash -Options: - --help Show help [boolean] - --version Show version number [boolean] -``` +These changes are explained in more detail below, with examples for easy reference. -### Subcommands +### Capitalize Chain Names -??? code "Aptos" - ```bash - worm aptos INSERT_COMMAND +In version 1.0, chain names are now consistent with the `Chain` type from the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, and must be capitalized. This affects all config properties where a chain is referenced, including `rpcs`, `rest`, `graphql`, and `chains`. -Commands: - worm aptos init-token-bridge Init token bridge contract - worm aptos init-wormhole Init Wormhole core contract - worm aptos deploy Deploy an Aptos package - worm aptos deploy-resource Deploy an Aptos package using a - resource account - worm aptos send-example-message Send example message - - worm aptos derive-resource-account Derive resource account address - - worm aptos derive-wrapped-address Derive wrapped coin type - - worm aptos hash-contracts Hash contract bytecodes for upgrade - worm aptos upgrade Perform upgrade after VAA has been - submitted - worm aptos migrate Perform migration after contract - upgrade - worm aptos faucet Request money from the faucet for a - given account - worm aptos start-validator Start a local aptos validator +=== "v0.x" -Options: - --help Show help [boolean] - --version Show version number [boolean] + ```typescript + const config: WormholeConnectConfig = { + rpcs: { + ethereum: 'INSERT_ETH_RPC_URL', + solana: 'INSERT_SOLANA_RPC_URL', + }, + }; ``` +=== "v1.x" -??? code "Edit VAA" - ```bash - worm edit-vaa INSERT_COMMAND - -Options: - --help Show help [boolean] - --version Show version number [boolean] - -v, --vaa vaa in hex format [string] [required] - -n, --network Network - [required] [choices: "mainnet", "testnet", "devnet"] - --guardian-set-index, --gsi guardian set index [number] - --signatures, --sigs comma separated list of signatures [string] - --wormscanurl, --wsu url to wormscan entry for the vaa that - includes signatures [string] - --wormscan, --ws if specified, will query the wormscan entry - for the vaa to get the signatures [boolean] - --emitter-chain-id, --ec emitter chain id to be used in the vaa - [number] - --emitter-address, --ea emitter address to be used in the vaa[string] - --nonce, --no nonce to be used in the vaa [number] - --sequence, --seq sequence number to be used in the vaa[string] - --consistency-level, --cl consistency level to be used in the vaa - [number] - --timestamp, --ts timestamp to be used in the vaa in unix - seconds [number] - -p, --payload payload in hex format [string] - --guardian-secret, --gs Guardian's secret key [string] + ```typescript + const config: WormholeConnectConfig = { + rpcs: { + Ethereum: 'INSERT_ETH_RPC_URL', + Solana: 'INSERT_SOLANA_RPC_URL', + }, + }; ``` -??? code "EVM" - ```bash - worm evm INSERT_COMMAND +You can find the complete list of supported chain names in the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/fa4ba4bc349a7caada809f209090d79a3c5962fe/core/base/src/constants/chains.ts#L12-L66){target=\_blank}. -Commands: - worm evm address-from-secret Compute a 20 byte eth address from a 32 - byte private key - worm evm storage-update Update a storage slot on an EVM fork - during testing (anvil or hardhat) - worm evm chains Return all EVM chains - worm evm info Query info about the on-chain state of - the contract - worm evm hijack Override the guardian set of the core - bridge contract during testing (anvil - or hardhat) - worm evm start-validator Start a local EVM validator +### Rename `env` to `network` -Options: - --help Show help [boolean] - --version Show version number [boolean] - --rpc RPC endpoint [string] - ``` +The `env` property has been renamed to `network`, with capitalized values. This change affects how you configure Testnet and Mainnet environments. -??? code "Generate" - ```bash - worm generate INSERT_COMMAND +=== "v0.x" -Commands: - worm generate registration Generate registration VAA - worm generate upgrade Generate contract upgrade VAA - worm generate attestation Generate a token attestation VAA - worm generate recover-chain-id Generate a recover chain ID VAA - worm generate Sets the default delivery provider - set-default-delivery-provider for the Wormhole Relayer contract + ```typescript + const config: WormholeConnectConfig = { + env: 'testnet', + }; + ``` +=== "v1.x" -Options: - --help Show help [boolean] - --version Show version number [boolean] - -g, --guardian-secret Guardians' secret keys (CSV) [string] [required] + ```typescript + const config: WormholeConnectConfig = { + network: 'Testnet', + }; ``` -??? code "Info" - ```bash - worm info INSERT_COMMAND +If you don’t explicitly set the `network` value, Connect will default to `Mainnet`. -Commands: - worm info chain-id Print the wormhole chain ID integer - associated with the specified chain - name - worm info contract Print contract address - - worm info emitter
Print address in emitter address - format - worm info origin
Print the origin chain and address - of the asset that corresponds to the - given chain and address. - worm info registrations Print chain registrations - - worm info rpc Print RPC address - worm info wrapped Print the wrapped address on the - target chain that corresponds with - the specified origin chain and - address. +```typescript +// Defaults to Mainnet +const config: WormholeConnectConfig = {}; +``` -Options: - --help Show help [boolean] - --version Show version number [boolean]
- ``` +For more information, refer to the [network constants list](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/networks.ts){target=\_blank}. -??? code "NEAR" - ```bash - worm near INSERT_COMMAND +### Rename `networks` to `chains` -Commands: - worm near contract-update Submit a contract update using our specific - APIs - worm near deploy Submit a contract update using near APIs +The `networks` property, which allowed whitelisting chains, is now renamed `chains`, and the chain names are capitalized. -Options: - --help Show help [boolean] - --version Show version number [boolean] - -m, --module Module to query [choices: "Core", "NFTBridge", "TokenBridge"] - -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] - --account Near deployment account [string] [required] - --attach Attach some near [string] - --target Near account to upgrade [string] - --mnemonic Near private keys [string] - --key Near private key [string] - -r, --rpc Override default rpc endpoint url [string] +=== "v0.x" + + ```typescript + const config: WormholeConnectConfig = { + networks: ['solana', 'ethereum'], + }; ``` +=== "v1.x" -??? code "Parse" - ```bash - worm parse INSERT_VAA + ```typescript + const config: WormholeConnectConfig = { + chains: ['Solana', 'Ethereum'], + }; + ``` -Positionals: - vaa vaa [string] +### Update `routes` to Use Route Plugins -Options: - --help Show help [boolean] - --version Show version number [boolean] - ``` +The `routes` property in Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. -??? code "Recover" - ```bash - worm recover INSERT_DIGEST INSERT_SIGNATURE +By default, if no `routes` property is set, Connect will provide routes for two core protocols: -Positionals: - digest digest [string] - signature signature [string] + - [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} + - [CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} -Options: - --help Show help [boolean] - --version Show version number [boolean] - ``` +For most use cases, integrators require more than the default routes. The new `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including both default and third-party routes. -??? code "Status" - ```bash - worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH +#### Available `route` Plugins -Positionals: - network Network [choices: - 'mainnet', - 'testnet', - 'devnet'] - chain Source chain - [choices: - 'unset', - 'solana', - 'ethereum', - 'terra', - 'bsc', - 'polygon', - 'avalanche', - 'oasis', - 'algorand', - 'aurora', - 'fantom', - 'karura', - 'acala', - 'klaytn', - 'celo', - 'near', - 'moonbeam', - 'neon', - 'terra2', - 'injective', - 'osmosis', - 'sui', - 'aptos', - 'arbitrum', - 'optimism', - 'gnosis', - 'pythnet', - 'xpla', - 'btc', - 'base', - 'sei', - 'rootstock', - 'scroll', - 'mantle', - 'blast', - 'xlayer', - 'linea', - 'berachain', - 'seievm', - 'wormchain', - 'cosmoshub', - 'evmos', - 'kujira', - 'neutron', - 'celestia', - 'stargaze', - 'seda', - 'dymension', - 'provenance', - 'sepolia', - 'arbitrum_sepolia', - 'base_sepolia', - 'optimism_sepolia', - 'holesky', - 'polygon_sepolia'] - tx Source transaction hash [string] +The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: -Options: - --help Show help [boolean] - --version Show version number [boolean] - ``` +???- tip "`route` Plugins" + - **`TokenBridgeRoute`** - manually redeemed Token Bridge route + - **`AutomaticTokenBridgeRoute`** - automatically redeemed (relayed) Token Bridge route + - **`CCTPRoute`** - manually redeemed CCTP route + - **`AutomaticCCTPRoute`** - automatically redeemed (relayed) CCTP route + - **`DEFAULT_ROUTES`** - array containing the four preceding routes (TokenBridgeRoute, AutomaticTokenBridgeRoute, CCTPRoute, AutomaticCCTPRoute) + - **`nttAutomaticRoute(nttConfig)`** - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route + - **`nttManualRoute(nttConfig)`** - function that returns the manually-redeemed NTT route + - **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array + - **`MayanRoute`** - route that offers multiple Mayan protocols + - **`MayanRouteSWIFT`** - route for Mayan’s Swift protocol only + - **`MayanRouteMCTP`** - route for Mayan’s MCTP protocol only + - **`MayanRouteWH`** - route for Mayan’s original Wormhole transfer protocol -??? code "Submit" - ```bash - worm submit INSERT_VAA +In addition to these routes, developers can create custom routes for their own Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. -Positionals: - vaa vaa [string] +For further details on the Route plugin interface, refer to the [Wormhole TypeScript SDK route code](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/route.ts){target=\_blank}. -Options: - --help Show help [boolean] - --version Show version number [boolean] - -c, --chain chain name -[choices: 'unset', - 'solana', - 'ethereum', - 'terra', - 'bsc', - 'polygon', - 'avalanche', - 'oasis', - 'algorand', - 'aurora', - 'fantom', - 'karura', - 'acala', - 'klaytn', - 'celo', - 'near', - 'moonbeam', - 'neon', - 'terra2', - 'injective', - 'osmosis', - 'sui', - 'aptos', - 'arbitrum', - 'optimism', - 'gnosis', - 'pythnet', - 'xpla', - 'btc', - 'base', - 'sei', - 'rootstock', - 'scroll', - 'mantle', - 'blast', - 'xlayer', - 'linea', - 'berachain', - 'seievm', - 'wormchain', - 'cosmoshub', - 'evmos', - 'kujira', - 'neutron', - 'celestia', - 'stargaze', - 'seda', - 'dymension', - 'provenance', - 'sepolia', - 'arbitrum_sepolia', - 'base_sepolia', - 'optimism_sepolia', - 'holesky', - 'polygon_sepolia'] - -n, --network Network - [required] - [choices: - 'mainnet', - 'testnet', - 'devnet'] - -a, --contract-address Contract to submit VAA to (override config) [string] - --rpc RPC endpoint [string] - --all-chains, --ac Submit the VAA to all chains except for the origin - chain specified in the payload - [boolean] [default: false] - ``` +Now that you know the available `route` plugins, let's explore some examples of configuring them. -??? code "Sui" - ```bash - worm sui INSERT_COMMAND +#### Example: Offer Only CCTP Transfers -Commands: - worm sui build-coin Build wrapped coin and dump bytecode. +To configure Connect to offer only USDC transfers via the CCTP route, use the following configuration: - Example: - worm sui build-coin -d 8 -v V__0_1_1 -n - testnet -r - "https://fullnode.testnet.sui.io:443" - worm sui deploy Deploy a Sui package - worm sui init-example-message-app Initialize example core message app - worm sui init-token-bridge Initialize token bridge contract - worm sui init-wormhole Initialize wormhole core contract - worm sui publish-example-message Publish message from example app via - core bridge - worm sui setup-devnet Setup devnet by deploying and - initializing core and token bridges and - submitting chain registrations. - worm sui objects Get owned objects by owner - worm sui package-id Get package ID from State object ID - worm sui tx Get transaction details +```typescript +import WormholeConnect, { + AutomaticCCTPRoute, + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -Options: - --help Show help [boolean] - --version Show version number [boolean] - ``` +const config: WormholeConnectConfig = { + routes: [AutomaticCCTPRoute], +}; -??? code "Transfer" - ```bash - worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK +; +``` -Options: - --help Show help [boolean] - --version Show version number [boolean] - --src-chain source chain [required] [choices: - 'solana', - 'ethereum', - 'terra', - 'bsc', - 'polygon', - 'avalanche', - 'oasis', - 'algorand', - 'aurora', - 'fantom', - 'karura', - 'acala', - 'klaytn', - 'celo', - 'near', - 'moonbeam', - 'neon', - 'terra2', - 'injective', - 'osmosis', - 'sui', - 'aptos', - 'arbitrum', - 'optimism', - 'gnosis', - 'pythnet', - 'xpla', - 'btc', - 'base', - 'sei', - 'rootstock', - 'scroll', - 'mantle', - 'blast', - 'xlayer', - 'linea', - 'berachain', - 'seievm', - 'wormchain', - 'cosmoshub', - 'evmos', - 'kujira', - 'neutron', - 'celestia', - 'stargaze', - 'seda', - 'dymension', - 'provenance', - 'sepolia', - 'arbitrum_sepolia', - 'base_sepolia', - 'optimism_sepolia', - 'holesky', - 'polygon_sepolia'] - --dst-chain destination chain - [required] [choices: - 'solana', - 'ethereum', - 'terra', - 'bsc', - 'polygon', - 'avalanche', - 'oasis', - 'algorand', - 'aurora', - 'fantom', - 'karura', - 'acala', - 'klaytn', - 'celo', - 'near', - 'moonbeam', - 'neon', - 'terra2', - 'injective', - 'osmosis', - 'sui', - 'aptos', - 'arbitrum', - 'optimism', - 'gnosis', - 'pythnet', - 'xpla', - 'btc', - 'base', - 'sei', - 'rootstock', - 'scroll', - 'mantle', - 'blast', - 'xlayer', - 'linea', - 'berachain', - 'seievm', - 'wormchain', - 'cosmoshub', - 'evmos', - 'kujira', - 'neutron', - 'celestia', - 'stargaze', - 'seda', - 'dymension', - 'provenance', - 'sepolia', - 'arbitrum_sepolia', - 'base_sepolia', - 'optimism_sepolia', - 'holesky', - 'polygon_sepolia'] - --dst-addr destination address [string] [required] - --token-addr token address [string] [default: native token] - --amount token amount [string] [required] - -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] - --rpc RPC endpoint [string] - ``` +#### Example: Offer All Default Routes and Third-Party Plugins -??? code "Verify VAA" - ```bash - worm verify-vaa INSERT_VAA, INSERT_NETWORK +In this example, Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. -Options: - --help Show help [boolean] - --version Show version number [boolean] - -v, --vaa vaa in hex format [string] [required] - -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] - ``` +```typescript +import WormholeConnect, { + DEFAULT_ROUTES, + nttRoutes, + MayanRouteSWIFT, + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; +import { myNttConfig } from './consts'; // Custom NTT configuration -## Examples +const config: WormholeConnectConfig = { + routes: [...DEFAULT_ROUTES, ...nttRoutes(myNttConfig), MayanRouteSWIFT], +}; -### VAA generation +; +``` -Use `generate` to create VAAs for testing. For example, use the following command to create an NFT bridge registration VAA: +This flexible plugin allows you to combine default routes (such as Token Bridge and CCTP) with third-party protocols, offering complete control over which routes are available in your application. -```bash -worm generate registration --module NFTBridge \ - --chain bsc \ - --contract-address 0x706abc4E45D419950511e474C7B9Ed348A4a716c \ - --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 -``` +### Update the `tokensConfig` Structure -The below example generates a token attestation VAA: +In Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. -```bash -worm generate attestation --emitter-chain ethereum \ - --emitter-address 11111111111111111111111111111115 \ - --chain ethereum \ - --token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \ - --decimals 6 \ - --symbol USDC \ - --name USDC \ - --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 -``` +Key Changes to `tokensConfig`: -### VAA parsing + - **Capitalized chain names** - all chain names, like `ethereum`, must now be capitalized, such as `Ethereum`, to maintain consistency with the rest of the Wormhole SDK + - **`wrappedTokens`** - this new key replaces `foreignAssets` and defines the wrapped token addresses on foreign chains, making it easier to manage cross-chain transfers. It consolidates the wrapped token addresses into a cleaner structure. These addresses must be specified to enable token transfers to and from the foreign chain via token bridge routes + - **Simplified decimals** - instead of using a map of decimal values for different chains, you now only need to provide a single decimals value for the token's native chain -Use `parse` to parse a VAA into JSON: +=== "v0.x" -```bash -worm parse $(worm-fetch-governance 13940208096455381020) -``` + In the old structure, the `foreignAssets` field defined the token’s presence on other chains, and `decimals` were mapped across multiple chains. -This example will fetch governance VAA `13940208096455381020` and print it as JSON: + ```typescript + import WormholeConnect, { + WormholeConnectConfig, + } from '@wormhole-foundation/wormhole-connect'; -```bash -# ...signatures elided -timestamp: 1651416474, -nonce: 1570649151, -emitterChain: 1, -emitterAddress: '0000000000000000000000000000000000000000000000000000000000000004', -sequence: 13940208096455381020n, -consistencyLevel: 32, -payload: { - module: 'Core', - type: 'GuardianSetUpgrade', - chain: 0, - newGuardianSetIndex: 2, - newGuardianSetLength: 19, - newGuardianSet: [ - '58cc3ae5c097b213ce3c81979e1b9f9570746aa5', - 'ff6cb952589bde862c25ef4392132fb9d4a42157', - '114de8460193bdf3a2fcf81f86a09765f4762fd1', - '107a0086b32d7a0977926a205131d8731d39cbeb', - '8c82b2fd82faed2711d59af0f2499d16e726f6b2', - '11b39756c042441be6d8650b69b54ebe715e2343', - '54ce5b4d348fb74b958e8966e2ec3dbd4958a7cd', - '66b9590e1c41e0b226937bf9217d1d67fd4e91f5', - '74a3bf913953d695260d88bc1aa25a4eee363ef0', - '000ac0076727b35fbea2dac28fee5ccb0fea768e', - 'af45ced136b9d9e24903464ae889f5c8a723fc14', - 'f93124b7c738843cbb89e864c862c38cddcccf95', - 'd2cc37a4dc036a8d232b48f62cdd4731412f4890', - 'da798f6896a3331f64b48c12d1d57fd9cbe70811', - '71aa1be1d36cafe3867910f99c09e347899c19c3', - '8192b6e7387ccd768277c17dab1b7a5027c0b3cf', - '178e21ad2e77ae06711549cfbb1f9c7a9d8096e8', - '5e1487f35515d02a92753504a8d75471b9f49edb', - '6fbebc898f403e4773e95feb15e80c9a99c8348d' - ] -} -``` + const config: WormholeConnectConfig = { + tokensConfig: { + WETH: { + key: 'WETH', + symbol: 'WETH', + nativeChain: 'ethereum', + icon: Icon.ETH, + tokenId: { + chain: 'ethereum', + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + }, + coinGeckoId: 'ethereum', + color: '#62688F', + decimals: { Ethereum: 18, default: 8 }, + foreignAssets: { + Solana: { + address: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs', + decimals: 8, + }, + }, + }, + }, + }; + ``` +=== "v1.x" -### Submitting VAAs + In v1.0, `foreignAssets` has been replaced with `wrappedTokens`, simplifying token transfers across chains by directly mapping wrapped token addresses. The `decimals` value is now a simple number representing the token’s decimals on its native chain. -Use `submit` to submit a VAA to a chain. It first parses the VAA and determines the destination chain and module. For example, a contract upgrade contains both the target chain and module, so the only required argument is the network moniker (`mainnet` or `testnet`): + ```typescript + import WormholeConnect, { + WormholeConnectConfig, + } from '@wormhole-foundation/wormhole-connect'; -```bash -worm submit $(cat my-nft-registration.txt) --network mainnet -``` + const config: WormholeConnectConfig = { + tokensConfig: { + WETH: { + key: 'WETH', + symbol: 'WETH', + nativeChain: 'Ethereum', // Chain name now capitalized + icon: Icon.ETH, + tokenId: { + chain: 'Ethereum', + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + }, + coinGeckoId: 'ethereum', + color: '#62688F', + decimals: 18, // Simplified decimals field + }, + }, + wrappedTokens: { + WETH: { + Solana: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs', + /* additional chains */ + }, + }, + }; + ``` -The script will ask you to specify the target chain for VAAs that don't have a specific target chain (like registrations or Guardian set upgrades). For example, to submit a Guardian set upgrade on all chains, simply run: +### Update NTT Configuration -```bash -worm-fetch-governance 13940208096455381020 > guardian-upgrade.txt -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain oasis -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain aurora -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain fantom -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain karura -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain acala -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain klaytn -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain avalanche -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain polygon -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain bsc -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain solana -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain terra -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain ethereum -worm submit $(cat guardian-upgrade.txt) --network mainnet --chain celo -``` +In Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. -The VAA payload type (Guardian set upgrade) specifies that this VAA should go to the core bridge, and the tool directs it there. +Key changes: -### Getting Info + - **Removed `nttGroups`** - the `nttGroups` property has been removed from the configuration and is now passed as an argument to the `nttRoutes` function + - **Direct NTT route configuration** - NTT routes are now defined more explicitly, allowing for a more organized structure when specifying tokens, chains, and managers -To get info about a contract (only EVM supported at this time), use the following command: +This change simplifies the configuration process by providing a cleaner, more flexible way to handle NTT routes across different chains. -```bash -worm evm info -c bsc -n mainnet -m TokenBridge -``` +=== "v0.x" -Running this command generates the following output: + In the previous version, `nttGroups` defined the NTT managers and transceivers for different tokens across multiple chains. -```bash -{ - "address": "0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7", - "wormhole": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B", - "implementation": "0x621199f6beB2ba6fbD962E8A52A320EA4F6D4aA3", - "isInitialized": true, - "tokenImplementation": "0x7f8C5e730121657E17E452c5a1bA3fA1eF96f22a", - "chainId": 4, - "finality": 15, - "evmChainId": "56", - "isFork": false, - "governanceChainId": 1, - "governanceContract": "0x0000000000000000000000000000000000000000000000000000000000000004", - "WETH": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", - "registrations": { - "Solana": "0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5", - "Ethereum": "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585", - "Terra": "0x0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2", - "Polygon": "0x0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde", - "Avalanche": "0x0000000000000000000000000e082f06ff657d94310cb8ce8b0d9a04541d8052", - "Oasis": "0x0000000000000000000000005848c791e09901b40a9ef749f2a6735b418d7564", - "Algorand": "0x67e93fa6c8ac5c819990aa7340c0c16b508abb1178be9b30d024b8ac25193d45", - "Aurora": "0x00000000000000000000000051b5123a7b0f9b2ba265f9c4c8de7d78d52f510f", - "Fantom": "0x0000000000000000000000007c9fc5741288cdfdd83ceb07f3ea7e22618d79d2", - "Karura": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624", - "Acala": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624", - "Klaytn": "0x0000000000000000000000005b08ac39eaed75c0439fc750d9fe7e1f9dd0193f", - "Celo": "0x000000000000000000000000796dff6d74f3e27060b71255fe517bfb23c93eed", - "Near": "0x148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7", - "Moonbeam": "0x000000000000000000000000b1731c586ca89a23809861c6103f0b96b3f57d92", - "Neon": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Terra2": "0xa463ad028fb79679cfc8ce1efba35ac0e77b35080a1abe9bebe83461f176b0a3", - "Injective": "0x00000000000000000000000045dbea4617971d93188eda21530bc6503d153313", - "Osmosis": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Sui": "0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5", - "Aptos": "0x0000000000000000000000000000000000000000000000000000000000000001", - "Arbitrum": "0x0000000000000000000000000b2402144bb366a632d14b83f244d2e0e21bd39c", - "Optimism": "0x0000000000000000000000001d68124e65fafc907325e3edbf8c4d84499daa8b", - "Gnosis": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Pythnet": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Xpla": "0x8f9cf727175353b17a5f574270e370776123d90fd74956ae4277962b4fdee24c", - "Btc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Base": "0x0000000000000000000000008d2de8d2f73f1f4cab472ac9a881c9b123c79627", - "Sei": "0x86c5fd957e2db8389553e1728f9c27964b22a8154091ccba54d75f4b10c61f5e", - "Rootstock": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Scroll": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", - "Mantle": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", - "Blast": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", - "Xlayer": "0x0000000000000000000000005537857664b0f9efe38c9f320f75fef23234d904", - "Linea": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Berachain": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Seievm": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Snaxchain": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Wormchain": "0xaeb534c45c3049d380b9d9b966f9895f53abd4301bfaff407fa09dea8ae7a924", - "Cosmoshub": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Evmos": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Kujira": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Neutron": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Celestia": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Stargaze": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Seda": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Dymension": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Provenance": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", - "ArbitrumSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", - "BaseSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", - "OptimismSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", - "Holesky": "0x0000000000000000000000000000000000000000000000000000000000000000", - "PolygonSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000" - } -} -``` + ```typescript + import WormholeConnect, { + nttRoutes, + WormholeConnectConfig, + } from '@wormhole-foundation/wormhole-connect'; -### Additional Info Examples + const config: WormholeConnectConfig = { + nttGroups: { + Lido_wstETH: { + nttManagers: [ + { + chainName: 'ethereum', + address: '0xb948a93827d68a82F6513Ad178964Da487fe2BD9', + tokenKey: 'wstETH', + transceivers: [ + { + address: '0xA1ACC1e6edaB281Febd91E3515093F1DE81F25c0', + type: 'wormhole', + }, + ], + }, + { + chainName: 'bsc', + address: '0x6981F5621691CBfE3DdD524dE71076b79F0A0278', + tokenKey: 'wstETH', + transceivers: [ + { + address: '0xbe3F7e06872E0dF6CD7FF35B7aa4Bb1446DC9986', + type: 'wormhole', + }, + ], + }, + ], + }, + }, + }; + ``` +=== "v1.x" -You can get the contract address for a module as follows: + In v1.0, `nttGroups` has been removed, and the configuration is passed to the NTT route constructor as an argument. The tokens and corresponding transceivers are now clearly defined within the `nttRoutes` configuration. -```bash -worm info rpc INSERT_NETWORK INSERT_CHAIN INSERT_MODULE -``` + ```typescript + import WormholeConnect, { + nttRoutes, + WormholeConnectConfig, + } from '@wormhole-foundation/wormhole-connect'; -To get the contract address for `NFTBridge` on BSC Mainnet, for example, you can provide the following command: + const config: WormholeConnectConfig = { + routes: [ + ...nttRoutes({ + tokens: { + Lido_wstETH: [ + { + chain: 'Ethereum', + manager: '0xb948a93827d68a82F6513Ad178964Da487fe2BD9', + token: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + transceiver: [ + { + address: '0xA1ACC1e6edaB281Febd91E3515093F1DE81F25c0', + type: 'wormhole', + }, + ], + }, + { + chain: 'Bsc', + manager: '0x6981F5621691CBfE3DdD524dE71076b79F0A0278', + token: '0x26c5e01524d2E6280A48F2c50fF6De7e52E9611C', + transceiver: [ + { + address: '0xbe3F7e06872E0dF6CD7FF35B7aa4Bb1446DC9986', + type: 'wormhole', + }, + ], + }, + ], + }, + }), + /* other routes */ + ], + }; + ``` -```bash -worm info contract mainnet bsc NFTBridge -``` + In this new structure, NTT routes are passed directly through the `nttRoutes` function, with the `token`, `chain`, `manager` and `transceiver` clearly defined for each supported asset. -You can get the RPC address for a chain as follows: - -```bash -worm info rpc INSERT_NETWORK INSERT_CHAIN -``` - -To get the RPC address for BSC Mainnet, for example, you can provide the following command: - -```bash -worm info rpc mainnet bsc -``` ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/toolkit/dev-env/ ---- BEGIN CONTENT --- ---- -title: Local Dev Environment -description: Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more. -categories: Solidity-SDK, Typescript-SDK ---- - -# Development Environment +### Update UI Configuration -Developers building for smart contract integration will want to set up a development environment to allow testing the full integration, possibly including VAA generation and relaying. +In Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. -## Tooling Installation +Key UI changes: -The [Wormhole CLI Tool](/docs/build/toolkit/cli/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/build/start-building/supported-networks/){target=\_blank}. + - **Consolidated UI properties** - many UI-related properties moved under a new top-level ui key for better organization + - **Removed `customTheme` and `mode`** - these properties have been removed in favor of a new top-level prop called `theme`, which simplifies theming and allows dynamic switching between themes -## Development Stages +#### UI Properties -Different approaches to development and testing are recommended at various stages of application development. +The following properties that were previously defined at the root level of the configuration are now part of the `ui` key: -### Initial Development + - `explorer` → `ui.explorer` - specifies the explorer to use for viewing transactions + - `bridgeDefaults` → `ui.defaultInputs` - sets default input values for the bridge, such as the source and destination chains and token + - `pageHeader` → `ui.pageHeader` - sets the title and header for the page + - `menu` → `ui.menu` - defines the menu items displayed in the interface + - `searchTx` → `ui.searchTx` - configures the transaction search functionality + - `partnerLogo` → `ui.partnerLogo` - displays a partner's logo on the interface + - `walletConnectProjectId` → `ui.walletConnectProjectId` - integrates WalletConnect into the UI + - `showHamburgerMenu` → `ui.showHamburgerMenu` - enables or disables the hamburger menu for navigation -During the initial development of an on-chain application, the best option is to use the native tools available in the environment. You can visit the following resources for more information: +Additionally, there are two new properties under `ui`: -- **[Environment](https://github.com/wormhole-foundation/wormhole){target=\_blank}** - select the folder for the desired network to learn about the recommended native toolset -- **[Mock Guardian](https://github.com/wormhole-foundation/wormhole/blob/main/sdk/js/src/mock/wormhole.ts){target=\_blank}** - it's recommended to set up a mock Guardian or Emitter to provide signed VAAsFor any program methods that require some message be sent or received. -- **[Wormhole Scaffolding repository](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/evm/ts-test/01_hello_world.ts){target=\_blank}** - example mock Guardian test + - **`ui.title`** - sets the title rendered in the top left corner of the UI. The default is "Wormhole Connect" + - **`ui.getHelpUrl`** - URL that Connect will render when an unknown error occurs, allowing users to seek help. This can link to a Discord server or any other support channel -Relying on native tools when possible allows for more rapid prototyping and iteration. +```typescript +import WormholeConnect, { + WormholeConnectConfig, +} from '@wormhole-foundation/wormhole-connect'; -### Integration +const config: WormholeConnectConfig = { + ui: { + title: 'My Custom Bridge Example', + getHelpUrl: 'https://examplehelp.com/', + menu: [ + { + label: 'Support', + href: 'https://examplehelp.com/support', + target: '_blank', + order: 1, // Order of appearance in the menu + }, + { + label: 'About', + href: 'https://examplehelp.com/about', + target: '_blank', + order: 2, + }, + ], + showHamburgerMenu: false, + }, +}; +``` -For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/build/start-building/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. +#### UI Configuration -!!! note - Variation in host environments causes unique issues, and the computational intensity of multiple simultaneous local validators can make setting them up difficult or time-consuming. You may prefer Testnets for the simplest integration testing. +In the old structure, UI-related settings like `explorer` and `bridgeDefaults` were defined at the root level of the configuration. In version 1.0, these properties are now organized under the `ui` key, improving the configuration's readability and manageability. -### Prepare for Deployment +=== "v0.x" -Once you've finished the application's initial development and performed integration testing, you should set up a CI test environment. The best option for that is likely to be [Tilt](https://tilt.dev/){target=\_blank} since it allows you to spin up any chains supported by Wormhole in a consistent environment. + ```typescript + const config: WormholeConnectConfig = { + bridgeDefaults: { + fromNetwork: 'solana', + toNetwork: 'ethereum', + tokenKey: 'USDC', + requiredNetwork: 'solana', + }, + showHamburgerMenu: true, + }; + ``` +=== "v1.x" -## Validator Setup with Tilt + ```typescript + const config: WormholeConnectConfig = { + ui: { + defaultInputs: { + fromChain: 'Solana', // Chain names now capitalized + toChain: 'Ethereum', + tokenKey: 'USDC', + requiredChain: 'Solana', + }, + showHamburgerMenu: true, + }, + }; + ``` -### Tilt -If you'd like to set up a local validator environment, follow the setup guide for Tilt. Tilt is a full-fledged Kubernetes deployment of every chain connected to Wormhole, along with a Guardian node. It usually takes 30 minutes to spin up fully, but it comes with all chains running out of the box. Refer to the [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} page for a complete guide to setting up and configuring Tilt. +#### Remove `customTheme` and `mode` Properties -## Deploying to Public Networks +In version 1.0, the `customTheme` and `mode` properties, which were previously used to set themes, have been removed. They have been replaced by a new top-level prop called `theme`, which allows for more flexibility and dynamic updates to themes. -### Testnet +Important details: -When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: + - The `theme` prop is not part of the `config` object and is passed separately to Wormhole Connect + - `config` cannot be modified after Connect has mounted, but the `theme` can be updated dynamically to support changes such as switching between light and dark modes or updating color schemes -```text -https://api.testnet.wormholescan.io -``` +=== "v0.x" -### Mainnet + ```typescript + const config: WormholeConnectConfig = { + customTheme: { + primaryColor: '#4266f5', + secondaryColor: '#ff5733', + }, + mode: 'dark', + }; -The Mainnet contract addresses are available on the page for each [environment](/docs/build/start-building/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: + ; + ``` +=== "v1.x" -```text -https://api.wormholescan.io -``` ---- END CONTENT --- + ```typescript + const theme: WormholeConnectTheme = { + mode: 'dark', // Can be dynamically changed + font: 'Arial', + button: { + primary: '#4266f5', + }, + }; -Doc-Content: https://wormhole.com/docs/build/toolkit/faqs/ ---- BEGIN CONTENT --- ---- -title: Toolkit FAQs -description: FAQs on Wormhole Toolkit, covering Wormholescan, CLI, SDKs (TypeScript, Solidity), Tilt, error handling, transaction history, and manual VAA submission. -categories: Solidity-SDK, Typescript-SDK ---- + ; + ``` -# Toolkit FAQs +### Removed Configuration Properties -## Why does the `toNative` function in the TypeScript SDK return an error? +Several configuration properties have been removed in Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. -The `toNative` function may return an error if the platform-specific module (such as Solana or EVM) is not correctly imported or passed into the Wormhole constructor. +Removed config keys: -To fix this, ensure the relevant platform module is imported and included when initializing Wormhole. For example, if you're working with Solana, make sure to import the Solana module and pass it into the Wormhole constructor like this: + - `cta` + - `cctpWarning` + - `pageSubHeader` + - `moreTokens` + - `moreChains` + - `ethBridgeMaxAmount` + - `wstETHBridgeMaxAmount` + - `customTheme` + - `mode` -```typescript -import solana from '@wormhole-foundation/sdk/solana'; -const wh = await wormhole('Testnet', [solana]); -``` +If your current setup includes any of these properties, you can safely remove them, as they are no longer supported in v1.0. -## How can I retrieve the history of previously bridged transactions? +## Use the CDN-Hosted Version of Wormhole Connect -To retrieve the history of previously bridged transactions, you can use the Wormholescan API. Use the following endpoint to query the transaction history for a specific address: +For those using the CDN-hosted version of Wormhole Connect, the package's installation and integration have been updated. You must install the Connect package from npm and use the new `wormholeConnectHosted` utility function. -```bash -https://api.wormholescan.io/api/v1/operations?address=INSERT_ADDRESS -``` +### Install and Integrate the Hosted Version -Simply replace `INSERT_ADDRESS_HERE` with the address you want to query. The API will return a list of operations, including details about previously bridged transactions. +1. Install the Connect package via npm: -???- example "Fetch transaction history for a specific address" ```bash - curl -X GET "https://api.wormholescan.io/api/v1/operations?address=0x05c009C4C1F1983d4B915C145F4E782de23d3A38" -H "accept: application/json" + npm install @wormhole-foundation/wormhole-connect@^1.0 ``` -## How can I manually submit a VAA to a destination chain in the correct format? +2. After installing the package, you can embed Connect into your page by adding the following code: -To manually submit a VAA (Verifiable Action Approval) to a destination chain, follow these steps: + ```typescript + import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; -1. **Obtain the VAA in Base64 format** - navigate to the **Advanced** tab in [Wormholescan](https://wormholescan.io/){target=\_blank} to find the VAA associated with the transaction you want to submit and copy the VAA in base64 format + const container = document.getElementById('connect')!; - ```bash - https://wormholescan.io/#/tx/INSERT_TX_HASH?view=advanced + wormholeConnectHosted(container); ``` -2. **Convert the VAA to hex** - you must convert the base64 VAA into a hexadecimal (hex) format before submitting it to the destination chain. This can be done using various online tools or via command-line utilities like `xxd` or a script in a language like Python +### Example: Custom Configuration for Hosted Version -3. **Submit the VAA through Etherscan (for EVM chains)** - once the VAA is in hex format, go to the [Etherscan UI](https://etherscan.io/){target=\_blank} and submit it through the [`TokenBridge`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} contract’s method (such as the `CompleteTransfer` function or `CompleteTransferWithPayload`) +The `wormholeConnectHosted` function accepts two parameters: `config` and `theme`. This allows you to customize the routes and apply a theme directly within the hosted version. Here’s an example of how you can pass a custom configuration: - - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/build/reference/contract-addresses/){target=\_blank} section +```typescript +import { + wormholeConnectHosted, + MayanRoute, +} from '@wormhole-foundation/wormhole-connect'; - - Interact with the smart contract through the Etherscan UI by pasting the hex-encoded VAA into the appropriate field +const container = document.getElementById('connect')!; -Following these steps, you can manually submit a VAA in the proper format to a destination chain. +wormholeConnectHosted(container, { + config: { + routes: [MayanRoute], + eventHandler: (e) => { + console.log('Connect event', e); + }, + }, + theme: { + background: { + default: '#004547', + }, + }, +}); +``` + +In this example, the `config` object defines the routes (in this case, using the Mayan route), while the `theme` object allows customization of the Connect interface (e.g., background color). --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/ +Doc-Content: https://wormhole.com/docs/products/connect/overview/ --- BEGIN CONTENT --- --- -title: Wormhole Tooling -description: This page lists key dev tools, including the WormholeScan Explorer, Wormhole CLI, Wormhole SDKs, and APIs for querying network data. -categories: Solidity-SDK +title: Wormhole Connect +description: With Wormhole Connect, you can seamlessly bridge digital assets and data across a wide range of supported blockchain networks. +categories: Connect, Transfer --- -# Wormhole Tooling - -Regardless of which network development environment you are using, there are a few Wormhole-specific tools you should know about. - -## Get Started - -
- -- :octicons-telescope-16:{ .lg .middle } **Wormholescan** +# Connect Overview - --- - - Wormholescan is an explorer for looking at individual transfer statuses on Mainnet and Testnet. - - [:custom-arrow: Review transactions on Wormholescan](https://wormholescan.io){target=\_blank} - -- :octicons-plug-16:{ .lg .middle } **Wormholescan API** +With the Wormhole Connect widget, you can enable users to perform multichain asset transfers directly within your application. Connect simplifies the complexity of bridging, offering a single, intuitive point of interaction for moving assets across diverse blockchains. This empowers you to access liquidity and opportunities across any connected network seamlessly. - --- - - Leverage the Wormholescan API to programmatically access Wormhole network data, including transaction details and VAAs. - - [:custom-arrow: Explore the Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} +## Key Features -- :octicons-code-square-16:{ .lg .middle } **Wormhole CLI Tool** +Connect's notable features include: - --- +- **In-app multichain transfers**: Bridge assets without leaving your app. +- **Customizable features**: Specify chains and custom RPCs, manage tokens, and select bridging [routes](/docs/products/connect/concepts/routes/){target=\_blank} such as Token Bridge, CCTP, or NTT. +- **Customizable UI**: Style the bridge interface to match your brand. +- **Optional destination gas**: Provide gas for initial transactions on the target chain. +- **Wrapped and native assets support**: Supports both wrapped and native tokens and integrates with Settlement. - The Wormhole CLI is a Swiss-Army knife utility command line tool. It is excellent for creating one-off VAAs, parsing VAAs, reading Wormhole contract configurations, and more. +Be sure to check the [Feature Support Matrix](/docs/products/connect/reference/support-matrix/#feature-support-matrix){target=\_blank} to find out which routes and features are supported for each chain. - [:custom-arrow: Get started with the CLI](/docs/build/toolkit/cli/) +## How It Works -- :octicons-code-square-16:{ .lg .middle } **Wormhole SDK** +When a user initiates a multichain transfer, Connect walks them through key steps and automates the transfer process behind the scenes, including: - --- +1. **Initiating the transfer**: Connect your chosen wallet to the source chain, select asset and source chain for the transfer. +2. **Finalize transfer setup**: Connect the destination wallet, select the target chain and select a bridging route (manual or automatic). +3. **Transaction submission on source chain**: Confirms the transfer details to trigger the asset lock or deposit on the initial blockchain. Connect will guide you through the transaction process. +4. **VAA or attestation creation**: Wormhole [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the source transaction and produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. +5. **Relaying to destination**: The VAA or attestation is automatically relayed to the destination chain. +6. **Verification on destination**: Contracts on the target chain receive and verify the incoming VAA. +7. **Asset release/minting**: Upon successful verification, the equivalent assets are either released or minted on the target chain and delivered to your wallet. - Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC transfers. +!!! tip + If you want more hands on experience with Connect, checkout [Portal Bridge](https://portalbridge.com/){target=\_blank}. - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/typescript-sdk/) +## Use Cases -- :octicons-code-square-16:{ .lg .middle } **Solidity SDK** +Here are some key use cases that highlight the power and versatility of Connect: - --- +- **Cross-Chain Swaps and Liquidity Aggregation** - Learn about Wormhole's Solidity SDK, including key components, interfaces, and tools for developing cross-chain decentralized applications on EVM-compatible blockchains. + - [**Connect**](/docs/products/connect/get-started/): Handles user-friendly asset transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Moves native assets across chains. + - [**Queries**](/docs/products/queries/overview/): Fetches real-time prices for optimal trade execution. - [:custom-arrow: Get started with the SDK](/docs/build/toolkit/solidity-sdk/) +- **Cross-Chain Payment Widgets** -- :octicons-beaker-16:{ .lg .middle } **Tilt** + - [**Connect**](/docs/products/connect/get-started/): Facilitates seamless payments in various tokens. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Ensures direct, native asset transfers. - --- +- **Web3 Game Asset Transfers** - Learn about Tilt, a Wormhole developer environment with a local Kubernetes set up for cross-chain testing with Guardian nodes and relayers for seamless development. + - [**Connect**](/docs/products/connect/get-started/): Provide a user-friendly way to move game tokens across chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/): Handle the underlying lock-and-mint logic securely. - [:custom-arrow: Get started with Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} +## Next Steps - +*Scroll down for details about each column.* -
- -## Additional Resources +| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | +|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| +| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | +| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | +| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | +| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | +| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | +| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | +| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | +| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | +| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | +| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | +| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | +| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | +| Base | ✅ | ✅ | ✅ | ✅ | ✅ | +| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | +| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | +| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | +| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | -
+## Feature Explanation {: #feature-explanation} -- :octicons-code-square-16:{ .lg .middle } **Wormhole Spy SDK** +### Token Bridge {: #token-bridge} - --- +Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. - The Wormhole Spy SDK allows you to listen to all the Guardian Network activity. +This route appears if both of the following conditions are satisfied: - [:custom-arrow: Check out the Spy SDK repository](https://github.com/wormhole-foundation/wormhole/tree/main/spydk/js){target=\_blank} + - Both the origin and destination chains support Token Bridge + - No non-Token Bridge routes are available for the selected token -- :octicons-pencil-16:{ .lg .middle } **VAA Parser** +### Token Bridge Relayer {: #token-bridge-relayer} - --- +On the [routes](/docs/products/connect/concepts/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. - The VAA Parser is a resource for parsing out details of an encoded VAA. +Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. - [:custom-arrow: Try the VAA Parser](https://wormholescan.io/#/developers/vaa-parser){target=\_blank} +This route appears if all of the following conditions are satisfied: -
---- END CONTENT --- +- Both the origin and destination chains support Token Bridge +- Both the origin and destination chains support Token Bridge relayer +- No non-Token Bridge routes are available for the selected token +- The relayer supports the selected token on the origin chain -Doc-Content: https://wormhole.com/docs/build/toolkit/solidity-sdk/ ---- BEGIN CONTENT --- ---- -title: Solidity SDK -description: How to use the Wormhole Solidity SDK for cross-chain messaging, token transfers, and integrating decentralized applications on EVM-compatible blockchains. -categories: Solidity-SDK ---- +### Circle CCTP {: #circle-cctp} -# Solidity SDK +[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. -## Introduction +This route appears if all of the following conditions are satisfied: -The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} simplifies cross-chain messaging on EVM-compatible chains by providing essential Solidity interfaces, utility libraries, and testing tools. It allows developers to build secure and efficient cross-chain decentralized applications (dApps) without manually interacting with Wormhole’s core contracts across multiple chains. +- Both the origin and destination chains support Circle CCTP +- The selected token is native Circle-issued USDC -By abstracting away complex interactions, the SDK drastically reduces the overhead associated with cross-chain development. It provides: +### ETH Bridge {: #eth-bridge} - - **Unified interfaces** - developers can use a standardized set of Solidity interfaces to handle cross-chain messaging, token transfers, and verifiable action approvals (VAAs) without needing to manage the underlying infrastructure - - **Automated message delivery** - the SDK leverages Wormhole’s relayer infrastructure, automatically delivering messages across chains, reducing the need for manual intervention, and simplifying gas management on the target chain - - **Seamless integration with Wormhole services** - the SDK integrates with Wormhole’s `TokenBridge` and Circle’s CCTP, providing built-in mechanisms for cross-chain asset transfers, making token bridges and cross-chain messaging easy to implement - - **Testing and development tools** - it comes with comprehensive tools for local testing and simulation, allowing developers to validate their cross-chain logic before deployment, minimizing the risk of errors in production environments +[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. -These features significantly streamline the development workflow by reducing complexity and offering tools compatible with various EVM versions. This helps developers avoid issues that arise from differences in EVM equivalence across chains. +This route appears if all of the following conditions are satisfied: -This guide covers installation, key concepts, and usage examples to help you build secure cross-chain applications using the SDK, from token transfers to advanced message passing. +- Both the origin and destination chains support the ETH Bridge +- The selected token is native ETH, wstETH, or canonical wETH -## Installation +### Gas Drop Off {: #gas-drop-off} -To install the SDK, use [Foundry and Forge](https://book.getfoundry.sh/getting-started/installation){target=\_blank}. This pulls the necessary libraries into your project: +A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. -```bash -forge install wormhole-foundation/wormhole-solidity-sdk@v0.1.0 -``` +This route appears if all of the following conditions are satisfied: -When developing cross-chain applications, ensure that the chains you target support the EVM version you’re using. For instance, the PUSH0 opcode (introduced in Solidity 0.8.20) may not be available on all chains. To avoid compatibility issues, you can set the EVM version in your `foundry.toml` file: +- Both the origin and destination chains support gas drop off +- An automatic route is selected +- The relayer accepts the selected token to swap into the gas token +--- END CONTENT --- -```toml -evm_version = "paris" -``` +Doc-Content: https://wormhole.com/docs/products/connect/tutorials/react-dapp/ +--- BEGIN CONTENT --- +--- +title: Integrate Connect into a React DApp Tutorial +description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. +categories: Connect, Transfer +--- -This ensures compatibility across all targeted chains, even if some do not yet support the latest EVM upgrades. +# Integrate Connect into a React DApp -## Key Considerations +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} -Before deploying applications using the Wormhole Solidity SDK, keep these considerations in mind: +## Introduction - - **Version compatibility** - the SDK is evolving, and using tagged releases for production is crucial, as the main branch may introduce breaking changes - - **IERC-20 remapping** - the SDK provides a remapping mechanism to handle potential conflicts between different implementations of IERC20, ensuring seamless integration with other libraries - - **Testing** - given the cross-chain dependencies, testing all integrations is critical to avoid issues in production environments +In this tutorial, we'll explore how to integrate [Wormhole Connect](/docs/products/connect/overview/){target=\_blank} to enable cross-chain token transfers and interactions. Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. -## Concepts and Components +While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any [blockchain supported by Wormhole](/docs/products/connect/reference/support-matrix/){target=\_blank}. In this example, we'll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. -The Wormhole Solidity SDK consists of key components that streamline cross-chain communication, allowing developers to securely and efficiently interact with Wormhole’s infrastructure. Below are the critical concepts and contracts you'll encounter when working with the SDK. +## Prerequisites -### Cross-Chain Messaging with the Wormhole Relayer SDK +To get started with Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. +Before starting this tutorial, ensure you have the following: -The [`WormholeRelayerSDK.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank} contract simplifies cross-chain messaging and asset transfers by integrating several necessary modules, including the Wormhole relayer. By automating message delivery between chains, the Wormhole relayer removes the need for developers to manage relayer infrastructure or handle gas on the target chain. Delivery providers handle the message payload, ensuring secure and efficient communication. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use +- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} +- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees -You can refer to the [Wormhole relayer documentation](/docs/build/core-messaging/wormhole-relayers/){target=\_blank} for more details. +## Set Up Connect for Sui Transfers -Key modules in the SDK include: +### Create a React Project - - **`Base.sol`** - the core module for cross-chain messaging. It provides utility functions like `onlyWormholeRelayer()` and `setRegisteredSender()`, ensuring that only messages from trusted relayers are processed +In this tutorial, we'll use [Next.js](https://nextjs.org/docs/app/getting-started){target=\_blank}, a popular framework built on top of React, to set up your app: - - **`TokenBase.sol`** - this module extends the base messaging functionality to support cross-chain token transfers. It includes utilities for securely sending and receiving tokens between EVM-compatible chains +1. Open your terminal and run the following command to create a new React app: - - **`CCTPBase.sol`** - designed for Circle’s Cross-Chain Transfer Protocol, this module manages asset transfers such as USDC between chains. It includes functionalities for both sending and receiving CCTP-based assets + ```bash + npx create-next-app@latest connect-tutorial + ``` - - **`CCTPAndTokenBase.sol`** - a combined module that supports token and CCTP-based asset transfers in a single implementation. This module simplifies development for applications needing to handle both types of transfers + We recommend enabling TypeScript and creating a `src/` directory during setup. Other options can be configured based on your preferences. -The Wormhole Solidity SDK offers a unified framework for cross-chain communication. Developers can select specific modules based on their application’s requirements, whether for messaging, token transfers, or CCTP. Each module includes built-in security measures, ensuring that only authorized senders or relayers are accepted, thereby protecting the application from unauthorized interactions. +2. Navigate into the project directory: -Please refer to the complete `WormholeRelayerSDK.sol` file below for further details. + ```bash + cd connect-tutorial + ``` -???- code "`WormholeRelayerSDK.sol`" - ```solidity - // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.19; -import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; -import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; -import "wormhole-sdk/constants/Chains.sol"; -import "wormhole-sdk/Utils.sol"; +### Install Connect -import {Base} from "wormhole-sdk/WormholeRelayer/Base.sol"; -import {TokenBase, TokenReceiver, TokenSender} from "wormhole-sdk/WormholeRelayer/TokenBase.sol"; -import {CCTPBase, CCTPReceiver, CCTPSender} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; -import {CCTPAndTokenBase, CCTPAndTokenReceiver, CCTPAndTokenSender} from "wormhole-sdk/WormholeRelayer/CCTPAndTokenBase.sol"; - ``` +Next, install the Connect package as a dependency by running the following command inside your project directory: -### Base Contract Overview +```bash +npm install @wormhole-foundation/wormhole-connect +``` -The [`Base.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/Base.sol){target=\_blank} contract is a core part of the Wormhole Solidity SDK, providing essential helper functions and modifiers for managing cross-chain messages securely via the Wormhole Relayer. It handles sender registration and message validation, ensuring only authorized senders from specific chains can send messages. +### Integrate Connect into the Application - - **`onlyWormholeRelayer()`** - a modifier that ensures only authorized messages from the Wormhole relayer contract are processed, restricting access to certain functions +Now, we need to modify the default `page.tsx` file to integrate Connect. We are going to use [version V1.0](/docs/products/connect/guides/upgrade/){target=\_blank} or later, make sure to check which version of Connect you are using. Open `src/app/page.tsx` and replace the content with the following code: - ```solidity - require( - msg.sender == address(wormholeRelayer), - "Msg.sender is not Wormhole Relayer" - ); - _; - } - ``` +=== "JavaScript" - - **`setRegisteredSender()`** - restricts message acceptance to a registered sender from a specific chain, ensuring messages are only processed from trusted sources + ```js + 'use client'; - ```solidity - uint16 sourceChain, - bytes32 sourceAddress - ) public { - require( - msg.sender == registrationOwner, - "Not allowed to set registered sender" - ); - registeredSenders[sourceChain] = sourceAddress; - } - ``` +import WormholeConnect from '@wormhole-foundation/wormhole-connect'; -These security measures ensure messages come from the correct source and are processed securely. Please refer to the complete `Base.sol` contract below for further details. +const config = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], +}; -???- code "`Base.sol`" - ```solidity - // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.19; +const theme = { + mode: 'light', + primary: '#78c4b6', +}; -import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; -import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "wormhole-sdk/Utils.sol"; +export default function Home() { + return ; +} + ``` -abstract contract Base { - IWormholeRelayer public immutable wormholeRelayer; - IWormhole public immutable wormhole; +=== "TypeScript" - address registrationOwner; - mapping(uint16 => bytes32) registeredSenders; + ```ts + 'use client'; - constructor(address _wormholeRelayer, address _wormhole) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - wormhole = IWormhole(_wormhole); - registrationOwner = msg.sender; - } +import WormholeConnect, { + WormholeConnectConfig, + WormholeConnectTheme, +} from '@wormhole-foundation/wormhole-connect'; - modifier onlyWormholeRelayer() { - require( - msg.sender == address(wormholeRelayer), - "Msg.sender is not Wormhole Relayer" - ); - _; - } +export default function Home() { + const config: WormholeConnectConfig = { + network: 'Testnet', + chains: ['Sui', 'Avalanche'], - modifier isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress) { - require( - registeredSenders[sourceChain] == sourceAddress, - "Not registered sender" - ); - _; - } + ui: { + title: 'SUI Connect TS Demo', + }, + }; - /** - * Sets the registered address for 'sourceChain' to 'sourceAddress' - * So that for messages from 'sourceChain', only ones from 'sourceAddress' are valid - * - * Assumes only one sender per chain is valid - * Sender is the address that called 'send' on the Wormhole Relayer contract on the source chain) - */ - function setRegisteredSender( - uint16 sourceChain, - bytes32 sourceAddress - ) public { - require( - msg.sender == registrationOwner, - "Not allowed to set registered sender" - ); - registeredSenders[sourceChain] = sourceAddress; - } + const theme: WormholeConnectTheme = { + mode: 'light', + primary: '#78c4b6', + }; + return ; } ``` -### Interface for Cross-Chain Messages +- Set `network` to `'Testnet'` - this ensures that Connect uses the testnet environment +- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche -The Wormhole Solidity SDK interacts with the Wormhole relayer for sending and receiving messages across EVM-compatible chains. The [`IWormholeRelayer`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeRelayer.sol){target=\_blank} and [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interfaces are central to cross-chain communication, enabling secure and efficient message delivery. +### Customize Connect -For detailed information on how to implement these interfaces, refer to the [Wormhole Relayer Interfaces documentation](/docs/build/core-messaging/wormhole-relayers/#wormhole-relayer-interfaces){target=\_blank}. This section covers: +To further customize Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Connect Configuration guide](/docs/products/connect/configuration/data/){target=\_blank}. - - **`IWormholeRelayer`** – methods for sending cross-chain messages, VAAs, and token transfers - - **`IWormholeReceiver`** – the required implementation for receiving cross-chain messages - - **`quoteEVMDeliveryPrice()`** – how to estimate gas and fees for cross-chain transactions +### Run the Application -These interfaces reduce the complexity of cross-chain dApp development by abstracting away the details of relayer infrastructure, ensuring that message delivery is handled efficiently. +Make sure you're in the root directory of your React app, and run the following command to start the application: -### Advanced Concepts +```bash +npm run dev +``` -For developers interested in exploring additional advanced topics, the following sections provide insights into key aspects of the SDK’s functionality. +Now your React app should be up and running, and Connect should be visible on `http://localhost:3000/`. You should see the Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. -???- note "Error Handling and Reverts" - The SDK defines several custom errors to help developers handle common issues like incorrect gas fees, invalid senders, and more. For example, `InvalidMsgValue` is thrown when the message value for a relayed message is erroneous. +## Transfer Tokens from Sui to Fuji - ```solidity - error InvalidMsgValue(uint256 msgValue, uint256 totalFee); - ``` +Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. -## Usage +To transfer tokens from Sui to Fuji in the Connect interface: -This section covers cross-chain messaging and token transfers and shows how to use the Wormhole Solidity SDK in real-world scenarios. +1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer +2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network +3. Enter the amount of SUI tokens you wish to transfer -### Send a Cross-Chain Message + ![](/docs/images/products/connect/tutorials/react-dapp/connect-1.webp){.half} -To send a cross-chain message, inherit from the base contract provided by the SDK and use its helper methods to define your message and sender address. Here’s a basic example: +4. Choose to view other routes + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-2.webp){.half} -```solidity -pragma solidity ^0.8.19; +5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) -import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/Base.sol"; + !!! note + It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. -contract CrossChainSender is Base { - constructor( - address _wormholeRelayer, - address _wormhole - ) Base(_wormholeRelayer, _wormhole) {} - - function sendMessage( - bytes memory message, - uint16 targetChain, - bytes32 targetAddress - ) external payable { - // Register sender and send message through WormholeRelayer - setRegisteredSender(targetChain, msg.sender); - onlyWormholeRelayer().sendPayloadToEvm( - targetChain, - address(targetAddress), - message, - 0, - 500_000 - ); - } -} -``` - -This contract extends `Base.sol` and allows sending cross-chain messages securely using the `WormholeRelayer`. - -### Send Tokens Across Chains - -The SDK enables seamless token transfers between EVM-compatible chains in addition to sending messages. To facilitate cross-chain token transfers, you can extend the SDK's `TokenSender` and `TokenReceiver` base contracts. + ![](/docs/images/products/connect/tutorials/react-dapp/connect-3.webp){.half} -```solidity -pragma solidity ^0.8.19; +6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain -import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/TokenBase.sol"; + ![](/docs/images/products/connect/tutorials/react-dapp/connect-4.webp){.half} -contract CrossChainTokenSender is TokenSender { - constructor( - address _wormholeRelayer, - address _wormhole - ) TokenSender(_wormholeRelayer, _wormhole) {} +7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet - function sendToken( - address token, - uint256 amount, - uint16 targetChain, - bytes32 targetAddress - ) external payable { - // Send tokens across chains - transferTokenToTarget(token, amount, targetChain, targetAddress); - } -} -``` + ![](/docs/images/products/connect/tutorials/react-dapp/connect-5.webp){.half} -In this example, `TokenSender` initiates a token transfer to another chain. The SDK’s built-in utilities securely handle token transfers, ensuring proper VAAs are generated and processed. +Once the transaction has been submitted, Connect will display the progress of the transfer. Monitor the status until you're prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. -### Receive Tokens Across Chains +## Claim Tokens on Fuji -To receive tokens on the target chain, implement a contract that inherits from `TokenReceiver` and overrides the `receiveWormholeMessages` function. +After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. -```solidity -pragma solidity ^0.8.19; +![](/docs/images/products/connect/tutorials/react-dapp/connect-6.webp){.half} -import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/TokenBase.sol"; +Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. -contract CrossChainTokenReceiver is TokenReceiver { - constructor( - address _wormholeRelayer, - address _wormhole - ) TokenReceiver(_wormholeRelayer, _wormhole) {} +![](/docs/images/products/connect/tutorials/react-dapp/connect-7.webp){.half} - // Function to handle received tokens from another chain - function receiveWormholeMessages( - bytes memory payload, - bytes[] memory additionalMessages, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 deliveryHash - ) external payable override { - // Process the received tokens here - receiveTokens(payload); - } -} -``` +## Resources -In this example, `TokenReceiver` allows the contract to handle tokens sent from the source chain. Once the cross-chain message is received, the `receiveWormholeMessages` function processes the incoming tokens. Always validate the message's authenticity and source. +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. -!!! note - Always verify the source of incoming messages and tokens to prevent unauthorized access to your contract. Please refer to the [Emitter Verification](/docs/build/core-messaging/core-contracts/#validating-the-emitter/){target=\_blank} section for more details. +## Conclusion -## Testing Environment +In this tutorial, you've gained hands-on experience with integrating Connect to enable cross-chain token transfers. You've learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. -The SDK includes built-in support for Forge-based testing, which allows you to test your cross-chain applications locally before deploying them to production. Testing with the same Solidity compiler version and configuration you plan to use in production is highly recommended to catch any potential issues early. +By following these steps, you've learned how to: -For a detailed example, check out the below repositories: +- Set up a React project tailored for cross-chain transfers +- Install and configure Connect to support multiple blockchains +- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers +- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks - - [Cross chain messaging](/docs/tutorials/solidity-sdk/cross-chain-contracts/){target=\_blank} - - [Cross chain token transfer](/docs/tutorials/solidity-sdk/cross-chain-token-contracts/){target=\_blank} +With these tools and knowledge, you're now equipped to build powerful cross-chain applications using Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/ +Doc-Content: https://wormhole.com/docs/products/messaging/get-started/ --- BEGIN CONTENT --- --- -title: Wormhole SDK -description: The Wormhole SDK provides tools for cross-chain communication, token bridges, and more, enabling developers to integrate with multiple blockchain environments. -categories: Typescript-SDK +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK --- -# Wormhole SDK - -## Get Started - -The Wormhole SDK provides developers with essential tools for cross-chain communication, token bridges, and more. This SDK enables seamless interaction between different blockchain environments with a focus on performance and usability. +# Get Started with Messaging -
- -- :octicons-book-16:{ .lg .middle } **Wormhole SDK** - - --- +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. - Learn about the core functionalities of the Wormhole SDK, including how to use its features for building cross-chain applications. - - [:custom-arrow: Explore the SDK](/docs/build/toolkit/typescript-sdk/wormhole-sdk/) - -- :octicons-code-16:{ .lg .middle } **Layouts** +## Prerequisites - --- +Before you begin, ensure you have the following: - Discover how to define, serialize, and deserialize data structures using the Wormhole SDK's layout system, ensuring efficient cross-chain communication. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions - [:custom-arrow: Learn about layouts](/docs/build/toolkit/typescript-sdk/sdk-layout/) +## Configure Your Messaging Environment -
---- END CONTENT --- +1. Create a directory and initialize a Node.js project: -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/protocols-payloads/ ---- BEGIN CONTENT --- ---- -title: Building Protocols and Payloads -description: Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. -categories: Typescript-SDK ---- + ```bash + mkdir core-message + cd core-message + npm init -y + ``` -# Building Protocols and Payloads +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: -## Introduction + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` -The [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} provides a flexible and powerful system for integrating cross-chain communication into your applications. A key feature of the SDK is its ability to define protocols—modular units representing distinct functionalities—and their associated payloads, which encapsulate the data required for specific operations within those protocols. +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: -This guide will help you understand how to build protocols and payloads in the SDK, covering: + ```bash + npx tsc --init + ``` - - The role of protocols and payloads in cross-chain communication - - The mechanics of registering protocols and payloads using the SDK - - Best practices for creating strongly typed layouts to ensure compatibility and reliability - - Real-world examples using the `TokenBridge` as a reference implementation + Make sure your `tsconfig.json` includes the following settings: -By the end of this guide, you’ll have a solid understanding of how to define, register, and use protocols and payloads in your projects. + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -## What is a Protocol? +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: -In the Wormhole SDK, a protocol represents a significant feature or functionality that operates across multiple blockchains. Protocols provide the framework for handling specific types of messages, transactions, or operations consistently and standardized. + ```bash + npm install @wormhole-foundation/sdk + ``` -Examples of Protocols: +5. Create a new file named `main.ts`: - - **`TokenBridge`** - enables cross-chain token transfers, including operations like transferring tokens and relaying payloads - - **`NTT (Native Token Transfers)`** - manages native token movements across chains + ```bash + touch main.ts + ``` -Protocols are defined by: +## Construct and Publish Your Message - - **A `name`** - a string identifier (e.g., `TokenBridge`, `Ntt`) - - **A set of `payloads`** - these represent the specific actions or messages supported by the protocol, such as `Transfer` or `TransferWithPayload` +1. Open `main.ts` and update the code there as follows: -Each protocol is registered in the Wormhole SDK, allowing developers to leverage its predefined features or extend it with custom payloads. + ```ts title="main.ts" + import { + wormhole, + signSendWait, + toNative, + encoding, + type Chain, + type Network, + type NativeAddress, + type WormholeMessageId, + type UnsignedTransaction, + type TransactionId, + type WormholeCore, + type Signer as WormholeSdkSigner, + type ChainContext, +} from '@wormhole-foundation/sdk'; +// Platform-specific modules +import EvmPlatformLoader from '@wormhole-foundation/sdk/evm'; +import { getEvmSigner } from '@wormhole-foundation/sdk-evm'; +import { + ethers, + Wallet, + JsonRpcProvider, + Signer as EthersSigner, +} from 'ethers'; -## What is a Payload? +/** + * The required value (SEPOLIA_PRIVATE_KEY) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ -A payload is a structured piece of data that encapsulates the details of a specific operation within a protocol. It defines the format, fields, and types of data used in a message or transaction. Payloads ensure consistency and type safety when handling complex cross-chain operations. +const SEPOLIA_PRIVATE_KEY = SEPOLIA_PRIVATE_KEY!; +// Provide a private endpoint RPC URL for Sepolia, defaults to a public node +// if not set +const RPC_URL = + process.env.SEPOLIA_RPC_URL || 'https://ethereum-sepolia-rpc.publicnode.com'; -Each payload is defined as: +async function main() { + // Initialize Wormhole SDK + const network = 'Testnet'; + const wh = await wormhole(network, [EvmPlatformLoader]); + console.log('Wormhole SDK Initialized.'); - - **A `layout`** - describes the binary format of the payload fields - - **A `literal`** - combines the protocol name and payload name into a unique identifier (e.g., `TokenBridge:Transfer`) + // Get the EVM signer and provider + let ethersJsSigner: EthersSigner; + let ethersJsProvider: JsonRpcProvider; -By registering payloads, developers can enforce type safety and enable serialization and deserialization for specific protocol operations. + try { + if (!SEPOLIA_PRIVATE_KEY) { + console.error('Please set the SEPOLIA_PRIVATE_KEY environment variable.'); + process.exit(1); + } -## Register Protocols and Payloads + ethersJsProvider = new JsonRpcProvider(RPC_URL); + const wallet = new Wallet(SEPOLIA_PRIVATE_KEY); + ethersJsSigner = wallet.connect(ethersJsProvider); + console.log( + `Ethers.js Signer obtained for address: ${await ethersJsSigner.getAddress()}`, + ); + } catch (error) { + console.error('Failed to get Ethers.js signer and provider:', error); + process.exit(1); + } -Protocols and payloads work together to enable cross-chain communication with precise type safety. For instance, in the `TokenBridge` protocol: + // Define the source chain context + const sourceChainName: Chain = 'Sepolia'; + const sourceChainContext = wh.getChain(sourceChainName) as ChainContext< + 'Testnet', + 'Sepolia', + 'Evm' + >; + console.log(`Source chain context obtained for: ${sourceChainContext.chain}`); + + // Get the Wormhole SDK signer, which is a wrapper around the Ethers.js + // signer using the Wormhole SDK's signing and transaction handling + // capabilities + let sdkSigner: WormholeSdkSigner; + try { + sdkSigner = await getEvmSigner(ethersJsProvider, ethersJsSigner); + console.log( + `Wormhole SDK Signer obtained for address: ${sdkSigner.address()}`, + ); + } catch (error) { + console.error('Failed to get Wormhole SDK Signer:', error); + process.exit(1); + } - - The protocol is registered under the `TokenBridge` namespace - - Payloads like `Transfer` or `AttestMeta` are linked to the protocol to handle specific operations + // Construct your message payload + const messageText = `HelloWormholeSDK-${Date.now()}`; + const payload: Uint8Array = encoding.bytes.encode(messageText); + console.log(`Message to send: "${messageText}"`); -Understanding the connection between these components is important for customizing or extending the SDK to suit your needs. + // Define message parameters + const messageNonce = Math.floor(Math.random() * 1_000_000_000); + const consistencyLevel = 1; -### Register Protocols + try { + // Get the core protocol client + const coreProtocolClient: WormholeCore = + await sourceChainContext.getWormholeCore(); + + // Generate the unsigned transactions + const whSignerAddress: NativeAddress = toNative( + sdkSigner.chain(), + sdkSigner.address(), + ); + console.log( + `Preparing to publish message from ${whSignerAddress.toString()} on ${ + sourceChainContext.chain + }...`, + ); -Registering a protocol establishes its connection to Wormhole's infrastructure, ensuring it interacts seamlessly with payloads and platforms while maintaining type safety and consistency. + const unsignedTxs: AsyncGenerator> = + coreProtocolClient.publishMessage( + whSignerAddress, + payload, + messageNonce, + consistencyLevel, + ); -#### How Protocol Registration Works + // Sign and send the transactions + console.log( + 'Signing and sending the message publication transaction(s)...', + ); + const txIds: TransactionId[] = await signSendWait( + sourceChainContext, + unsignedTxs, + sdkSigner, + ); -Protocol registration involves two key tasks: + if (!txIds || txIds.length === 0) { + throw new Error('No transaction IDs were returned from signSendWait.'); + } + const primaryTxIdObject = txIds[txIds.length - 1]; + const primaryTxid = primaryTxIdObject.txid; - - **Mapping protocols to interfaces** - connect the protocol to its corresponding interface, defining its expected behavior across networks (`N`) and chains (`C`). This ensures type safety, similar to strong typing, by preventing runtime errors if protocol definitions are incorrect - - **Linking protocols to platforms** - specify platform-specific implementations if needed, or use default mappings for platform-agnostic protocols + console.log(`Primary transaction ID for parsing: ${primaryTxid}`); + console.log( + `View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/${primaryTxid}`, + ); -For example, here's the `TokenBridge` protocol registration: + console.log( + '\nWaiting a few seconds for transaction to propagate before parsing...', + ); + await new Promise((resolve) => setTimeout(resolve, 8000)); -```typescript -declare module '../../registry.js' { - export namespace WormholeRegistry { - interface ProtocolToInterfaceMapping { - TokenBridge: TokenBridge; + // Retrieve VAA identifiers + console.log( + `Attempting to parse VAA identifiers from transaction: ${primaryTxid}...`, + ); + const messageIds: WormholeMessageId[] = + await sourceChainContext.parseTransaction(primaryTxid); + + if (messageIds && messageIds.length > 0) { + const wormholeMessageId = messageIds[0]; + console.log('--- VAA Identifiers (WormholeMessageId) ---'); + console.log(' Emitter Chain:', wormholeMessageId.chain); + console.log(' Emitter Address:', wormholeMessageId.emitter.toString()); + console.log(' Sequence:', wormholeMessageId.sequence.toString()); + console.log('-----------------------------------------'); + } else { + console.error( + `Could not parse Wormhole message IDs from transaction ${primaryTxid}.`, + ); } - interface ProtocolToPlatformMapping { - TokenBridge: EmptyPlatformMap<'TokenBridge'>; + } catch (error) { + console.error( + 'Error during message publishing or VAA identifier retrieval:', + error, + ); + if (error instanceof Error && error.stack) { + console.error('Stack Trace:', error.stack); } } } - -``` -This code snippet: +main().catch((e) => { + console.error('Critical error in main function (outer catch):', e); + if (e instanceof Error && e.stack) { + console.error('Stack Trace:', e.stack); + } + process.exit(1); +}); + ``` - - Maps the `TokenBridge` protocol to its interface to define how it operates - - Links the protocol to a default platform mapping via `EmptyPlatformMap` + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. -You can view the full implementation in the [`TokenBridge` protocol file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L14-L70){target=\_blank}. +2. Run the script using the following command: -#### Platform-Specific Protocols + ```bash + npx tsx main.ts + ``` -Some protocols require platform-specific behavior. For instance, the EVM-compatible Wormhole Registry maps native addresses for Ethereum-based chains: + You will see terminal output similar to the following: -```typescript -declare module '@wormhole-foundation/sdk-connect' { - export namespace WormholeRegistry { - interface PlatformToNativeAddressMapping { - Evm: EvmAddress; - } - } -} +
+npx tsx main.ts +Wormhole SDK Initialized. +Ethers.js Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Source chain context obtained for: Sepolia +Wormhole SDK Signer obtained for address: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Message to send: "HelloWormholeSDK-1748362375390" +Preparing to publish message from 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 on Sepolia... +Signing and sending the message publication transaction(s)... +Primary Transaction ID for parsing: 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +View on Sepolia Etherscan: https://sepolia.etherscan.io/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508 +Waiting a few seconds for transaction to propagate before parsing... +Attempting to parse VAA identifiers from transaction: + 0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508... +--- VAA Identifiers (WormholeMessageId) --- + Emitter Chain: Sepolia + Emitter Address: 0x000000000000000000000000cd8bcd9a793a7381b3c66c763c3f463f70de4e12 + Sequence: 1 +----------------------------------------- + +
-registerNative(_platform, EvmAddress); -``` +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages -This ensures that `EvmAddress` is registered as the native address type for EVM-compatible platforms. See the [EVM platform address file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/platforms/evm/src/address.ts#L98-L106){target=\_blank} for details. +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. -### Register Payloads +## Next Steps -[Payload registration](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts){target=\_blank} enables developers to define, serialize, and handle custom message types within their protocols. It establishes the connection between a protocol and its payloads, ensuring seamless integration, type enforcement, and runtime efficiency. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. +--- END CONTENT --- -This process ties a protocol to its payloads using a combination of: +Doc-Content: https://wormhole.com/docs/products/messaging/guides/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Core Contracts +description: This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +categories: Basics +--- - - **Payload literals** - unique identifiers in the format `:`. These literals map each payload to a layout - - **Payload layouts** - structures that define the binary representation of payload data - - **The payload factory** - a centralized runtime registry that maps payload literals to layouts for dynamic resolution and serialization +# Get Started with Core Contracts -These components work together to streamline the definition and management of protocol payloads. +## Introduction -#### How Payload Registration Works +Wormhole's Core Contracts, deployed on each supported blockchain network, enable the fundamental operations of sending and receiving cross-chain messages. -Payload registration involves: +While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -1. **Define payload layouts** - create layouts to structure your payloads. For instance, a protocol might use a `TransferWithPayload` layout: +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. - ```typescript - export const transferWithPayloadLayout = < - const P extends CustomizableBytes = undefined ->( - customPayload?: P -) => - [ - payloadIdItem(3), - ...transferCommonLayout, - { name: 'from', ...universalAddressItem }, - customizableBytes({ name: 'payload' }, customPayload), - ] as const; - ``` - -2. **Register payloads** - use `registerPayloadTypes` to map payload literals to their layouts: +## Prerequisites - ```typescript - registerPayloadTypes('ProtocolName', protocolNamedPayloads); - ``` +To interact with the Wormhole Core Contract, you'll need the following: -3. **Access registered payloads** - use the [`getPayloadLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/9105de290c91babbf8ad031bd89cc75ee38739c8/core/definitions/src/vaa/functions.ts#L19-L23){target=\_blank} function to fetch the layout for a specific payload literal. This method ensures that the correct layout is retrieved dynamically and safely: +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on - ```typescript - const layout = getPayloadLayout('ProtocolName:PayloadName'); - ``` +## How to Interact with Core Contracts -These steps link payload literals and their layouts, enabling seamless runtime handling. +Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole Core Contracts. The primary functionality revolves around: -#### The Payload Factory +- **Sending messages** - submitting messages to the Wormhole network for cross-chain communication +- **Receiving and verifying messages** - validating messages received from other chains via the Wormhole network -At the core of the payload registration process is the `payloadFactory`, a registry that manages the mapping between payload literals and layouts: +While the implementation details of the Core Contracts vary by network, the core functionality remains consistent across chains. -```typescript -export const payloadFactory = new Map(); +### Sending Messages -export function registerPayloadType( - protocol: ProtocolName, - name: string, - layout: Layout -) { - const payloadLiteral = composeLiteral(protocol, name); - if (payloadFactory.has(payloadLiteral)) { - throw new Error(`Payload type ${payloadLiteral} already registered`); - } - payloadFactory.set(payloadLiteral, layout); -} - -``` +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. - - The `payloadFactory` ensures each payload literal maps to its layout uniquely - - The [`registerPayloadType`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts#L46-L52){target=\_blank} function adds individual payloads, while [`registerPayloadTypes`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts#L62-L64){target=\_blank} supports bulk registration +=== "EVM" -This implementation ensures dynamic, efficient handling of payloads at runtime. + The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: -## Integrate Protocols with Payloads + ```solidity + function publishMessage( + uint32 nonce, + bytes memory payload, + uint8 consistencyLevel +) external payable returns (uint64 sequence); + ``` -Integrating payloads with protocols enables dynamic identification through payload literals, while serialization and deserialization ensure their binary representation is compatible across chains. For more details on these processes, refer to the [Layouts page](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank}. + ??? interface "Parameters" -### Payload Discriminators + `nonce` ++"uint32"++ + + A free integer field that can be used however you like. Note that changing the `nonce` will result in a different digest. -Payload discriminators are mechanisms in the Wormhole SDK that dynamically identify and map incoming payloads to their respective layouts at runtime. They are relevant for protocols like `TokenBridge`, enabling efficient handling of diverse payload types while ensuring type safety and consistent integration. + --- -#### How Discriminators Work + `payload` ++"bytes memory"++ + + The content of the emitted message. Due to the constraints of individual blockchains, it may be capped to a certain maximum length. -Discriminators evaluate serialized binary data and determine the corresponding payload layout by inspecting fixed fields or patterns within the data. Each payload layout is associated with a payload literal (e.g., `TokenBridge:Transfer` or `TokenBridge:TransferWithPayload`). + --- -This system ensures: + `consistencyLevel` ++"uint8"++ + + A value that defines the required level of finality that must be reached before the Guardians will observe and attest to emitted events. - - **Dynamic runtime identification** - payloads are parsed based on their content, even if a single protocol handles multiple payload types - - **Strict type enforcement** - discriminators leverage layout mappings to prevent invalid payloads from being processed + ??? interface "Returns" -Below is an example of how the Wormhole SDK builds a discriminator to distinguish between payload layouts: + `sequence` ++"uint64"++ + + A unique number that increments for every message for a given emitter (and implicitly chain). This, combined with the emitter address and emitter chain ID, allows the VAA for this message to be queried from the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank}. + + ??? interface "Example" -```typescript -export function layoutDiscriminator( - layouts: readonly Layout[], - allowAmbiguous?: B -): Discriminator { - // Internal logic to determine distinguishable layouts - const [distinguishable, discriminator] = internalBuildDiscriminator(layouts); - if (!distinguishable && !allowAmbiguous) { - throw new Error('Cannot uniquely distinguish the given layouts'); - } + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); - return ( - !allowAmbiguous - ? (encoded: BytesType) => { - const layout = discriminator(encoded); - return layout.length === 0 ? null : layout[0]; - } - : discriminator - ) as Discriminator; -} - -``` +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - - [`layoutDiscriminator`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/9105de290c91babbf8ad031bd89cc75ee38739c8/core/base/src/utils/layout.ts#L16){target=\_blank} takes a list of layouts and generates a function that can identify the appropriate layout for a given serialized payload - - The `allowAmbiguous` parameter determines whether layouts with overlapping characteristics are permitted +// Check fee and send parameters -### Real-World Example: Token Bridge Protocol +// Create the HelloWorldMessage struct +HelloWorldMessage memory parsedMessage = HelloWorldMessage({ + payloadID: uint8(1), + message: helloWorldMessage +}); -Integrating protocols with their respective payloads exemplifies how the Wormhole SDK leverages layouts and type-safe registration mechanisms to ensure efficient cross-chain communication. This section focuses on how protocols like `TokenBridge` use payloads to facilitate specific operations. +// Encode the HelloWorldMessage struct into bytes +bytes memory encodedMessage = encodeMessage(parsedMessage); -#### Token Bridge Protocol and Payloads +// Send the HelloWorld message by calling publishMessage on the +// wormhole core contract and paying the Wormhole protocol fee. +messageSequence = wormhole.publishMessage{value: wormholeFee}( + 0, // batchID + encodedMessage, + wormholeFinality() +); + ``` -The `TokenBridge` protocol enables cross-chain token transfers through its payloads. Key payloads include: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. - - **`Transfer`** - handles basic token transfer operations - - **`TransferWithPayload`** - extends the `Transfer` payload to include custom data, enhancing functionality +=== "Solana" -Payloads are registered to the `TokenBridge` protocol via the `PayloadLiteralToLayoutMapping` interface, which links payload literals (e.g., `TokenBridge:Transfer`) to their layouts. + The `wormhole_anchor_sdk::wormhole` module and the Wormhole program account can be used to pass a message directly to the Core Contract via the `wormhole::post_message` function: -Additionally, the protocol uses reusable layouts like [`transferCommonLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/76b20317b0f68e823d4e6c4a2e41bb2a7705c64f/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts#L29C7-L47){target=\_blank} and extends them in more specialized layouts such as [`transferWithPayloadLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/76b20317b0f68e823d4e6c4a2e41bb2a7705c64f/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts#L49-L57){target=\_blank}: + ```rs + pub fn post_message<'info>( + ctx: CpiContext<'_, '_, '_, 'info, PostMessage<'info>>, + batch_id: u32, + payload: Vec, + finality: Finality + ) -> Result<()> + ``` -```typescript -export const transferWithPayloadLayout = < - const P extends CustomizableBytes = undefined ->( - customPayload?: P -) => - [ - payloadIdItem(3), - ...transferCommonLayout, - { name: 'from', ...universalAddressItem }, - customizableBytes({ name: 'payload' }, customPayload), - ] as const; -``` + ??? interface "Parameters" -This layout includes: + `ctx` ++"CpiContext<'_, '_, '_, 'info, PostMessage<'info>>"++ + + Provides the necessary context for executing the function, including the accounts and program information required for the Cross-Program Invocation (CPI). - - A `payloadIdItem` to identify the payload type - - Common fields for token and recipient details - - A customizable `payload` field for additional data + ??? child "Type `pub struct CpiContext<'a, 'b, 'c, 'info, T>`" -#### Use the Discriminator + ```rs + pub struct CpiContext<'a, 'b, 'c, 'info, T> + where + T: ToAccountMetas + ToAccountInfos<'info>, + { + pub accounts: T, + pub remaining_accounts: Vec>, + pub program: AccountInfo<'info>, + pub signer_seeds: &'a [&'b [&'c [u8]]], + } + ``` -To manage multiple payloads, the `TokenBridge` protocol utilizes a discriminator to distinguish between payload types dynamically. For example: + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/anchor-lang/0.29.0/anchor_lang/context/struct.CpiContext.html){target=\_blank}. -```typescript -const tokenBridgePayloads = ['Transfer', 'TransferWithPayload'] as const; + ??? child "Type `PostMessage<'info>`" -export const getTransferDiscriminator = lazyInstantiate(() => - payloadDiscriminator([_protocol, tokenBridgePayloads]) -); -``` + ```rs + pub struct PostMessage<'info> { + pub config: AccountInfo<'info>, + pub message: AccountInfo<'info>, + pub emitter: AccountInfo<'info>, + pub sequence: AccountInfo<'info>, + pub payer: AccountInfo<'info>, + pub fee_collector: AccountInfo<'info>, + pub clock: AccountInfo<'info>, + pub rent: AccountInfo<'info>, + pub system_program: AccountInfo<'info>, + } + ``` - - The [`getTransferDiscriminator`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L67-L70){target=\_blank} function dynamically evaluates payloads using predefined layouts - - This ensures that each payload type is processed according to its unique structure and type-safe layout + For more information, please refer to the [`wormhole_anchor_sdk` Rust docs](https://docs.rs/wormhole-anchor-sdk/latest/wormhole_anchor_sdk/wormhole/instructions/struct.PostMessage.html){target=\_blank}. -#### Register Payloads to Protocols + --- -Here’s how the `TokenBridge` protocol connects its payloads to the Wormhole SDK: + `batch_id` ++"u32"++ + + An identifier for the message batch. -```typescript -declare module '../../registry.js' { - export namespace WormholeRegistry { - interface PayloadLiteralToLayoutMapping - extends RegisterPayloadTypes< - 'TokenBridge', - typeof tokenBridgeNamedPayloads - > {} - } -} + --- -registerPayloadTypes('TokenBridge', tokenBridgeNamedPayloads); -``` + `payload` ++"Vec"++ + + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. -This registration links the `TokenBridge` payload literals to their respective layouts, enabling serialization and deserialization at runtime. + --- -You can explore the complete `TokenBridge` protocol and payload definitions in the [`TokenBridge` layout file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts){target=\_blank}. + `finality` ++"Finality"++ + + Specifies the level of finality or confirmation required for the message. + + ??? child "Type `Finality`" -#### Token Bridge Payloads + ```rs + pub enum Finality { + Confirmed, + Finalized, + } + ``` + + ??? interface "Returns" -The following payloads are registered for the `TokenBridge` protocol: + ++"Result<()>"++ + + The result of the function’s execution. If the function completes successfully, it returns `Ok(())`, otherwise it returns `Err(E)`, indicating that an error occurred along with the details about the error + + ??? interface "Example" - - **`AttestMeta`** - used for token metadata attestation - - **`Transfer`** - facilitates token transfers - - **`TransferWithPayload`** - adds a custom payload to token transfers + ```rust + let fee = ctx.accounts.wormhole_bridge.fee(); +// ... Check fee and send parameters -These payloads and their layouts are defined in the [`TokenBridge` layout file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts){target=\_blank}. +let config = &ctx.accounts.config +let payload: Vec = HelloWorldMessage::Hello { message }.try_to_vec()?; -### Other Protocols: Native Token Transfers (NTT) +// Invoke `wormhole::post_message`. +wormhole::post_message( + CpiContext::new_with_signer( + ctx.accounts.wormhole_program.to_account_info(), + wormhole::PostMessage { + // ... Set fields + }, + &[ + // ... Set seeds + ], + ), + config.batch_id, + payload, + config.finality.into(), +)?; + ``` -While this guide focuses on the `TokenBridge` protocol, other protocols, like NTT, follow a similar structure. + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. - - NTT manages the transfer of native tokens across chains - - Payloads such as `WormholeTransfer` and `WormholeTransferStandardRelayer` are registered to the protocol using the same patterns for payload literals and layouts - - The same mechanisms for type-safe registration and payload discriminators apply, ensuring reliability and extensibility +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -For more details, you can explore the [NTT implementation in the SDK](https://github.com/wormhole-foundation/example-native-token-transfers/blob/00f83aa215338b1b8fd66f522bd0f45be3e98a5a/sdk/definitions/src/ntt.ts){target=\_blank}. ---- END CONTENT --- +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/sdk-layout/ ---- BEGIN CONTENT --- ---- -title: Data Layouts -description: Learn how to efficiently define, serialize, and deserialize data structures using Wormhole SDK's layout system for cross-chain communication. -categories: Typescript-SDK ---- +### Receiving Messages -# Data Layouts +The way a message is received and handled depends on the environment. -## Introduction +=== "EVM" -The [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} uses the [layout package](https://www.npmjs.com/package/binary-layout){target=\_blank} to define, serialize, and deserialize data structures efficiently. This modular system ensures consistent data formatting and cross-environment compatibility, benefiting projects that require robust handling of structured data. + On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. -By understanding the layout mechanism, you’ll be able to: + ```solidity + function parseAndVerifyVM( + bytes calldata encodedVM +) external view returns (VM memory vm, bool valid, string memory reason); + ``` - - Define data structures (numbers, arrays, and custom types) - - Efficiently serialize and deserialize data using the SDK’s utilities - - Handle protocol-specific layouts with ease + ??? interface "Parameters" -This guide is beneficial for developers looking to integrate Wormhole into their applications or protocols, especially those dealing with complex payloads or cross-chain communication. + `encodedVM` ++"bytes calldata"++ + + The encoded message as a Verified Action Approval (VAA), which contains all necessary information for verification and processing. -## Key Concepts + ??? interface "Returns" -### Layout Items + `vm` ++"VM memory"++ + + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. -A layout defines how data structures should be serialized (converted into binary format) and deserialized (converted back into their original structure). This ensures consistent data formatting when transmitting information across different blockchain environments. + ??? child "Struct `VM`" -Layouts are composed of [layout items](https://github.com/nonergodic/layout/blob/main/src/items.ts){target=\_blank}, which describe individual fields or sets of fields in your data. Each layout item specifies: + ```solidity + struct VM { + uint8 version; + uint32 timestamp; + uint32 nonce; + uint16 emitterChainId; + bytes32 emitterAddress; + uint64 sequence; + uint8 consistencyLevel; + bytes payload; + uint32 guardianSetIndex; + Signature[] signatures; + bytes32 hash; + } + ``` - - **`name`** - name of the field - - **`binary`** - type of data (e.g., `uint`, `bytes`) - - **`size`** - byte length for fixed-size fields within uint and bytes items only + For more information, refer to the [`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}. -Layout items can represent: + --- + + `valid` ++"bool"++ + + A boolean indicating whether the VAA is valid or not. + + --- - - **Primitive types** - basic data types like unsigned integers (`uint`) or byte arrays (`bytes`) - - **Composite types** - more complex structures, such as arrays or nested objects + `reason` ++"string"++ + + If the VAA is not valid, a reason will be provided -Below is an example of a layout that might be used to serialize a message across the Wormhole protocol: + ??? interface "Example" -```typescript -const exampleLayout = [ - { name: 'sourceChain', binary: 'uint', size: 2 }, - { name: 'orderSender', binary: 'bytes', size: 32 }, - { name: 'redeemer', binary: 'bytes', size: 32 }, - { name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 }, -] as const; -``` + ```solidity + function receiveMessage(bytes memory encodedMessage) public { + // Call the Wormhole core contract to parse and verify the encodedMessage + ( + IWormhole.VM memory wormholeMessage, + bool valid, + string memory reason + ) = wormhole().parseAndVerifyVM(encodedMessage); -In this example: + // Perform safety checks here - - `sourceChain` is a 2-byte unsigned integer (`uint`) identifying the source blockchain - - `orderSender` is a fixed-length 32-byte array representing the sender's address - - `redeemer` is another 32-byte array used for the redeemer’s address - - `redeemerMessage` is a variable-length byte sequence, with its length specified by a 4-byte integer + // Decode the message payload into the HelloWorldMessage struct + HelloWorldMessage memory parsedMessage = decodeMessage( + wormholeMessage.payload + ); -This layout definition ensures that all necessary data fields are consistently encoded and can be correctly interpreted when they are deserialized. + // Your custom application logic here +} + ``` -### Serialization and Deserialization + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. -Serialization converts structured data into binary format; deserialization reverses this, reconstructing the original objects. +=== "Solana" -You can serialize data using the `serializeLayout` function: + On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken. -```typescript -const serialized = serializeLayout(fillLayout, exampleFill); -``` + Retrieve the raw message data: -To deserialize the binary data back into a structured object, use the `deserializeLayout` function: + ```rs + let posted_message = &ctx.accounts.posted; + posted_message.data() + ``` -```typescript -const deserialized = deserializeLayout(fillLayout, serialized); -``` + ??? interface "Example" -### Custom Conversions + ```rust + pub fn receive_message(ctx: Context, vaa_hash: [u8; 32]) -> Result<()> { + let posted_message = &ctx.accounts.posted -Layouts also allow for custom conversions, which help map complex or custom types (like chain IDs or universal addresses) into a more usable format. This is useful when serializing or deserializing data that doesn’t fit neatly into simple types like integers or byte arrays. + if let HelloWorldMessage::Hello { message } = posted_message.data() { + // Check message + // Your custom application logic here + Ok(()) + } else { + Err(HelloWorldError::InvalidMessage.into()) + } +} + + ``` -For example, consider a custom conversion for a chain ID: + View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -```typescript -const chainCustomConversion = { - to: (chainId: number) => toChain(chainId), - from: (chain: Chain) => chainToChainId(chain), -} satisfies CustomConversion; - -``` +#### Validating the Emitter -This setup allows Wormhole to convert between human-readable formats and binary-encoded data used in payloads. +When processing cross-chain messages, it's critical to ensure that the message originates from a trusted sender (emitter). This can be done by verifying the emitter address and chain ID in the parsed VAA. -### Error Handling +Typically, contracts should provide a method to register trusted emitters and check incoming messages against this list before processing them. For example, the following check ensures that the emitter is registered and authorized: -The layout system performs error checks during serialization and deserialization. An error is thrown if data is incorrectly sized or in the wrong format. Refer to the below example: +```solidity +require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); +``` + +This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. ```typescript -try { - deserializeLayout(fillLayout, corruptedData); -} catch (error) { - console.error('Error during deserialization:', error.message); -} +const tx = await receiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) +); + +await tx.wait(); ``` -## Application of Layouts +#### Additional Checks -This section will focus on applying the concepts explained earlier through examples. These will help developers better understand how to define layouts, serialize and deserialize data, and use custom conversions where needed. +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: -### Defining Layouts +- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? -To get started with layouts in Wormhole, you need to define your structure. A layout is simply a list of fields (layout items) describing how each data piece will be serialized. +The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. -Consider the following layout for a payload: +## Source Code References -```typescript -const exampleLayout = [ - { name: 'sourceChain', binary: 'uint', size: 2 }, - { name: 'orderSender', binary: 'bytes', size: 32 }, - { name: 'redeemer', binary: 'bytes', size: 32 }, - { name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 }, -] as const; -``` +For a deeper understanding of the Core Contract implementation for a specific blockchain environment and to review the actual source code, please refer to the following links: -In this example: +- [Algorand Core Contract source code](https://github.com/wormhole-foundation/wormhole/blob/main/algorand/wormhole_core.py){target=\_blank} +- [Aptos Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/aptos/wormhole){target=\_blank} +- [EVM Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/ethereum/contracts){target=\_blank} ([`IWormhole.sol` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}) +- [NEAR Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/near/contracts/wormhole){target=\_blank} +- [Solana Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/solana/bridge/program){target=\_blank} +- [Sui Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/sui/wormhole){target=\_blank} +- [Terra Core Contract source code](https://github.com/wormhole-foundation/wormhole/tree/main/terra/contracts/wormhole){target=\_blank} +--- END CONTENT --- - - `sourceChain` is an unsigned integer (uint) of 2 bytes - - `orderSender` is a 32-byte fixed-length byte array - - `redeemer` is another 32-byte byte array - - `redeemerMessage` is a length-prefixed byte array, with the length specified by a 4-byte integer +Doc-Content: https://wormhole.com/docs/products/messaging/guides/wormhole-relayers/ +--- BEGIN CONTENT --- +--- +title: Wormhole-Deployed Relayers +description: Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +categories: Relayers, Basics +--- -### Serialize Data +# Wormhole Relayer -Once a layout is defined, the next step is to serialize data according to that structure. You can accomplish this using the `serializeLayout` function from the Wormhole SDK. +## Introduction -```typescript -const examplePayload = { - sourceChain: 6, - orderSender: new Uint8Array(32), - redeemer: new Uint8Array(32), - redeemerMessage: new Uint8Array([0x01, 0x02, 0x03]), -}; +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. -const serializedData = serializeLayout(exampleLayout, examplePayload); -``` +This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. -This takes the data structure (`examplePayload`) and serializes it according to the rules defined in the layout (`exampleLayout`). The result is a `Uint8Array` representing the serialized binary data. +## Get Started with the Wormhole Relayer -### Deserialize Data +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. -Deserialization is the reverse of serialization. Given a serialized `Uint8Array`, we can convert it back into its original structure using the `deserializeLayout` function. +To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying. -```typescript -const deserializedPayload = deserializeLayout(exampleLayout, serializedData); -``` +
+ ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp) +
The components outlined in blue must be implemented.
+
-This will output the structured object, making it easy to work with data transmitted or received from another chain. +### Wormhole Relayer Interfaces -### Handling Variable-Length Fields +There are three relevant interfaces to discuss when utilizing the Wormhole relayer module: -One relevant aspect of Wormhole SDK's layout system is the ability to handle variable-length fields, such as arrays and length-prefixed byte sequences. +- [**`IWormholeRelayer`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeRelayer.sol){target=\_blank} - the primary interface by which you send and receive messages. It allows you to request the sending of messages and VAAs +- [**`IWormholeReceiver`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IWormholeReceiver.sol){target=\_blank} - this is the interface you are responsible for implementing. It allows the selected delivery provider to deliver messages/VAAs to your contract +- [**`IDeliveryProvider`**](https://github.com/wormhole-foundation/wormhole/blob/main/relayer/ethereum/contracts/interfaces/relayer/IDeliveryProvider.sol){target=\_blank} - this interface represents the delivery pricing information for a given relayer network. Each delivery provider implements this on every blockchain they support delivering from -For instance, if you want to serialize or deserialize a message where the length of the content isn't known beforehand, you can define a layout item with a `lengthSize` field. +## Interact with the Wormhole Relayer -```typescript -{ name: 'message', binary: 'bytes', lengthSize: 4 } -``` +To start interacting with the Wormhole relayer in your contracts, you'll need to import the `IWormholeRelayer` interface and set up a reference using the contract address to the Wormhole-deployed relayer on the supported network of your choice. -This tells the SDK to read or write the message's length (in 4 bytes) and then handle the content. +To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -## Nested Layouts and Strong Typing +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. -The Wormhole SDK simplifies handling complex structures with nested layouts and strong typing. Nested layouts clearly represent hierarchical data, while strong typing ensures data consistency and catches errors during development. +Your initial set up should resemble the following: -### Nested Layout +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; -In complex protocols, layouts can contain nested structures. Nested layouts become relevant here, allowing you to represent hierarchical data (such as transactions or multi-part messages) in a structured format. +import "wormhole-solidity-sdk/interfaces/IWormholeRelayer.sol"; -Refer to the following nested layout where a message contains nested fields: +contract Example { + IWormholeRelayer public wormholeRelayer; -```typescript -const nestedLayout = [ - { - name: 'source', - binary: 'bytes', - layout: [ - { name: 'chainId', binary: 'uint', size: 2 }, - { name: 'sender', binary: 'bytes', size: 32 }, - ], - }, - { - name: 'redeemer', - binary: 'bytes', - layout: [ - { name: 'address', binary: 'bytes', size: 32 }, - { name: 'message', binary: 'bytes', lengthSize: 4 }, - ], - }, -] as const satisfies Layout; + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } +} ``` -In this layout: - - - `source` is an object with two fields: `chainId` and `sender` - - `redeemer` is another object with two fields: `address` and a length-prefixed `message` - -### Strong Typing +The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. -One of the benefits of using the Wormhole SDK in TypeScript is its support for strong typing. This ensures that serialized and deserialized data conform to expected structures, reducing errors during development by enforcing type checks at compile time. +### Send a Message -Using TypeScript, the `LayoutToType` utility provided by the SDK automatically generates a strongly typed structure based on the layout: +To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. -```typescript -type NestedMessage = LayoutToType; +```solidity +function sendPayloadToEvm( + // Chain ID in Wormhole format + uint16 targetChain, + // Contract Address on target chain we're sending a message to + address targetAddress, + // The payload, encoded as bytes + bytes memory payload, + // How much value to attach to the delivery transaction + uint256 receiverValue, + // The gas limit to set on the delivery transaction + uint256 gasLimit +) external payable returns ( + // Unique, incrementing ID, used to identify a message + uint64 sequence +); ``` -This ensures that when you serialize or deserialize data, it matches the expected structure. +!!! tip + To reduce transaction confirmation time, you can lower the consistency level using the [`sendToEvm`](https://github.com/wormhole-foundation/wormhole/blob/v{{repositories.wormhole.version}}/sdk/js/src/relayer/relayer/send.ts#L33){target=\_blank} method. -```typescript -const message: NestedMessage = { - source: { - chainId: 6, - sender: new Uint8Array(32), - }, - redeemer: { - address: new Uint8Array(32), - message: new Uint8Array([0x01, 0x02, 0x03]), - }, -}; +The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. + +```solidity +function quoteEVMDeliveryPrice( + // Chain ID in Wormhole format + uint16 targetChain, + // How much value to attach to delivery transaction + uint256 receiverValue, + // The gas limit to attach to the delivery transaction + uint256 gasLimit +) external view returns ( + // How much value to attach to the send call + uint256 nativePriceQuote, + uint256 targetChainRefundPerGasUnused +); ``` -Attempting to assign data of incorrect types will result in a compile-time error. The Wormhole SDK's layout system enforces strong types, reducing runtime errors and improving code reliability. +This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. -### Serialization and Deserialization with Nested Layouts +In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: -You can serialize and deserialize nested structures in the same way as simpler layouts: +```solidity +// Get a quote for the cost of gas for delivery +(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + valueToSend, + GAS_LIMIT +); -```typescript -const serializedNested = serializeLayout(nestedLayout, message); -const deserializedNested = deserializeLayout(nestedLayout, serializedNested); +// Send the message +wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(payload), + valueToSend, + GAS_LIMIT +); ``` -Strong typing in TypeScript ensures that the message object conforms to the nested layout structure. This reduces the risk of data inconsistency during cross-chain communication. +### Receive a Message -## Commonly Used Layouts +To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). -The Wormhole SDK includes predefined layouts frequently used in cross-chain messaging. These layouts are optimized for standard fields such as chain IDs, addresses, and signatures. You can explore the complete set of predefined layouts in the [`layout-items` directory](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/layout-items){target=\_blank} of the Wormhole SDK. +```solidity +function receiveWormholeMessages( + bytes memory payload, // Message passed by source contract + bytes[] memory additionalVaas, // Any additional VAAs that are needed (Note: these are unverified) + bytes32 sourceAddress, // The address of the source contract + uint16 sourceChain, // The Wormhole chain ID + bytes32 deliveryHash // A hash of contents, useful for replay protection +) external payable; +``` -### Chain ID Layouts +The logic inside the function body may be whatever business logic is required to take action on the specific payload. -Chain ID layouts in the Wormhole SDK derive from a common foundation: `chainItemBase`. This structure defines the binary representation of a chain ID as a 2-byte unsigned integer, ensuring consistency across serialization and deserialization processes. +## Delivery Guarantees -#### Base Structure +The Wormhole relayer protocol is intended to create a service interface whereby mutually distrustful integrators and delivery providers can work together to provide a seamless dApp experience. You don't trust the delivery providers with your data, and the delivery providers don't trust your smart contract. The primary agreement between integrators and delivery providers is that when a delivery is requested, the provider will attempt to deliver the VAA within the provider's stated delivery timeframe. -This simple structure is the blueprint for more specific layouts by standardizing the binary format and size. +This creates a marketplace whereby providers can set different price levels and service guarantees. Delivery providers effectively accept the slippage risk premium of delivering your VAAs in exchange for a set fee rate. Thus, the providers agree to deliver your messages even if they do so at a loss. -```typescript -const chainItemBase = { binary: 'uint', size: 2 } as const; -``` +Delivery providers should set their prices such that they turn a profit on average but not necessarily on every single transfer. Thus, some providers may choose to set higher rates for tighter guarantees or lower rates for less stringent guarantees. -#### Dynamic Chain ID Layout +## Delivery Statuses -The dynamic chain ID layout, [`chainItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/chain.ts#L13-L40){target=\_blank}, extends `chainItemBase` by adding flexible custom conversion logic. It enables runtime validation of chain IDs, supports optional null values, and restricts chain IDs to a predefined set when needed. +All deliveries result in one of the following four outcomes before the delivery provider's delivery timeframe. When they occur, these outcomes are emitted as EVM events from the Wormhole relayer contract. The four possible outcomes are: -```typescript -export const chainItem = < - const C extends readonly Chain[] = typeof chains, - const N extends boolean = false, ->(opts?: { - allowedChains?: C; - allowNull?: N; -}) => - ({ - ...chainItemBase, // Builds on the base structure - custom: { - to: (val: number): AllowNull => { ... }, - from: (val: AllowNull): number => { ... }, - }, - }); -``` +- (0) Delivery Success +- (1) Receiver Failure +- (2) Forward Request Success +- (3) Forward Request Failure -This layout is versatile. It allows the serialization of human-readable chain names (e.g., `Ethereum`) to numeric IDs (e.g., `1`) and vice versa. This is particularly useful when working with dynamic configurations or protocols supporting multiple chains. +A receiver failure is a scenario in which the selected provider attempted the delivery but it could not be completely successfully. The three possible causes for a delivery failure are: -#### Fixed Chain ID Layout +- The target contract does not implement the `IWormholeReceiver` interface +- The target contract threw an exception or reverted during the execution of `receiveWormholeMessages` +- The target contract exceeded the specified `gasLimit` while executing `receiveWormholeMessages` -The fixed chain ID layout, [`fixedChainItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/chain.ts#L42-L49){target=\_blank}, is more rigid. It also extends `chainItemBase`, but the custom field is hardcoded for a single chain. This eliminates runtime validation and enforces strict adherence to a specific chain. +All three of these scenarios can be avoided with correct design by the integrator, and thus, it is up to the integrator to resolve them. Any other scenario that causes a delivery to not be performed should be considered an outage by some component of the system, including potentially the blockchains themselves. -```typescript -export const fixedChainItem = (chain: C) => ({ - ...chainItemBase, // Builds on the base structure - custom: { - to: chain, - from: chainToChainId(chain), - }, -}); - -``` +`Forward Request Success` and `Forward Failure` represent when the delivery succeeded and the user requested a forward during the delivery. If the user has enough funds left over as a refund to complete the forward, the forward will be executed, and the status will be `Forward Request Success`. Otherwise, it will be `Forward Request Failure`. -This layout allows developers to efficiently serialize and deserialize messages involving a single, fixed chain ID. +## Other Considerations -### Address Layout +Some implementation details should be considered during development to ensure safety and a pleasant UX. Ensure that your engineering efforts have appropriately considered each of the following areas: -The Wormhole SDK uses a Universal Address Layout to serialize and deserialize blockchain addresses into a standardized format. This layout ensures that addresses are always represented as fixed 32-byte binary values, enabling seamless cross-chain communication. +- Receiving a message from a relayer +- Checking for expected emitter +- Calling `parseAndVerify` on any additional VAAs +- Replay protection +- Message ordering (no guarantees on order of messages delivered) +- Forwarding and call chaining +- Refunding overpayment of `gasLimit` +- Refunding overpayment of value sent -#### Base Structure +## Track the Progress of Messages with the Wormhole CLI -The [`universalAddressItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/universalAddress.ts#L7-L14){target=\_blank} defines the layout for addresses. It uses the binary type bytes and enforces a fixed size of 32 bytes for consistency. +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: -```typescript -export const universalAddressItem = { - binary: 'bytes', - size: 32, - custom: { - to: (val: Uint8Array): UniversalAddress => new UniversalAddress(val), - from: (val: UniversalAddress): Uint8Array => val.toUint8Array(), - } satisfies CustomConversion, -} as const satisfies LayoutItem; - -``` +=== "Mainnet" -This layout ensures consistent address handling by defining the following: + ```bash + worm status mainnet ethereum INSERT_TRANSACTION_HASH + ``` - - **Serialization** - converts a high-level `UniversalAddress` object into raw binary (32 bytes) for efficient storage or transmission - - **Deserialization** - converts raw binary back into a `UniversalAddress` object, enabling further interaction in a human-readable or programmatic format +=== "Testnet" -### Signature Layout + ```bash + worm status testnet ethereum INSERT_TRANSACTION_HASH + ``` -In the Wormhole SDK, the Signature Layout defines how to serialize and deserialize cryptographic signatures. These signatures verify message authenticity and ensure data integrity, particularly in Guardian-signed VAAs. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. -#### Base Structure +## Step-by-Step Tutorial -The `signatureLayout` specifies the binary structure of a secp256k1 signature. It divides the signature into three components: +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. +--- END CONTENT --- -```typescript -const signatureLayout = [ - { name: 'r', binary: 'uint', size: 32 }, - { name: 's', binary: 'uint', size: 32 }, - { name: 'v', binary: 'uint', size: 1 }, -] as const satisfies Layout; -``` +Doc-Content: https://wormhole.com/docs/products/messaging/overview/ +--- BEGIN CONTENT --- +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- -This layout provides a clear binary format for the secp256k1 signature, making it efficient to process within the Wormhole protocol. +# Messaging Overview -#### Layout with Custom Conversion +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. -The [`signatureItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/signature.ts#L15-L22){target=\_blank} builds upon the `signatureLayout` by adding custom conversion logic. This conversion transforms raw binary data into a high-level `Signature` object and vice versa. +## Key Features -```typescript -export const signatureItem = { - binary: 'bytes', - layout: signatureLayout, - custom: { - to: (val: LayoutToType) => - new Signature(val.r, val.s, val.v), - from: (val: Signature) => ({ r: val.r, s: val.s, v: val.v }), - } satisfies CustomConversion, Signature>, -} as const satisfies BytesLayoutItem; - -``` +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. -The `custom` field ensures seamless integration of raw binary data with the `Signature` class, encapsulating signature-specific logic. +## How It Works -## Advanced Use Cases +The messaging flow consists of several core components: -The Wormhole SDK’s layout system is designed to handle various data structures and serialization needs. This section will explore more advanced use cases, such as handling conditional data structures, fixed conversions, and optimizing serialization performance. +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. -???- code "Switch Statements for Conditional Layouts" +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) - In some cases, the structure of serialized data might change based on a specific field, such as a payload ID. The switch layout type conditionally defines layouts based on a value. +## Use Cases - For example, different message types can be identified using a payload ID, and the layout for each message can be determined at runtime: +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. - ```typescript - const switchLayout = { - binary: 'switch', - idSize: 1, // size of the payload ID - idTag: 'messageType', // tag to identify the type of message - layouts: [ - [[1, 'messageType1'], fillLayout], // layout for type 1 - [[2, 'messageType2'], fastFillLayout], // layout for type 2 - ], -} as const satisfies Layout; - ``` +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** - The switch statement helps developers parse multiple payload types using the same structure, depending on a control field like an ID. + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. -???- code "Fixed Conversions and Omitted Fields" +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** - Fixed conversions and omitted fields allow developers to handle known, static data without including it in every serialization or deserialization operation. For instance, when specific fields in a layout always hold a constant value, they can be omitted from the deserialized object. + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. - **Example: Fixed Conversion** +- **Gas Abstraction** - In some cases, a field may always contain a predefined value. The layout system supports fixed conversions, allowing developers to “hard-code” these values: + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. - ```typescript - const fixedConversionLayout = { - binary: 'uint', - size: 2, - custom: { - to: 'Ethereum', - from: chainToChainId('Ethereum'), - }, -} as const satisfies Layout; - ``` +- **Bridging Intent Library** - **Example: Omitted Fields** + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. - Omitted fields are useful for handling padding or reserved fields that do not carry meaningful information and can safely be excluded from the deserialized output: +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** - ```typescript - const omittedFieldLayout = [ - { name: 'reserved', binary: 'uint', size: 2, omit: true }, -] as const satisfies Layout; - ``` + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. - In this example, `reserved` is a padding field with a fixed, non-dynamic value that serves no functional purpose. It is omitted from the deserialized result but still considered during serialization to maintain the correct binary format. +## Next Steps - Only fields with a fixed, known value, such as padding or reserved fields, should be marked as `omit: true`. Fields with meaningful or dynamic information, such as `sourceChain` or `version`, must remain in the deserialized structure to ensure data integrity and allow seamless round-trip conversions between serialized and deserialized representations. +Follow these steps to work with Wormhole Messaging: -## Integration with Wormhole Protocol +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. +--- END CONTENT --- -The layout system facilitates seamless interaction with the Wormhole protocol, mainly when dealing with VAAs. These cross-chain messages must be serialized and deserialized to ensure they can be transmitted and processed accurately across different chains. +Doc-Content: https://wormhole.com/docs/products/messaging/tutorials/cross-chain-contracts/ +--- BEGIN CONTENT --- +--- +title: Create Cross-Chain Contracts +description: Learn how to create cross-chain contracts using Wormhole's Solidity SDK. Deploy contracts on Avalanche and Celo Testnets and send messages across chains. +--- -### VAAs and Layouts +# Create Cross-Chain Messaging Contracts -VAAs are the backbone of Wormhole’s cross-chain communication. Each VAA is a signed message encapsulating important information such as the originating chain, the emitter address, a sequence number, and Guardian signatures. The Wormhole SDK leverages its layout system to define, serialize, and deserialize VAAs, ensuring data integrity and chain compatibility. +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-wormhole-messaging){target=\_blank} -#### Base VAA Structure +## Introduction -The Wormhole SDK organizes the VAA structure into three key components: +Wormhole's cross-chain messaging allows smart contracts to interact seamlessly across multiple blockchains. This enables developers to build decentralized applications that leverage the strengths of different networks, whether it's Avalanche, Celo, Ethereum, or beyond. In this tutorial, we'll explore using [Wormhole's Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} to create cross-chain contracts to send and receive messages across chains. - - [**Header**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L37-L41){target=\_blank} - contains metadata such as the Guardian set index and an array of Guardian signatures - - [**Envelope**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} - includes chain-specific details such as the emitter chain, address, sequence, and [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} - - **Payload** - provides application-specific data, such as the actual message or operation being performed +Wormhole's messaging infrastructure simplifies data transmission, event triggering, and transaction initiation across blockchains. In this tutorial, we'll guide you through a simple yet powerful hands-on demonstration that showcases this practical capability. We'll deploy contracts on two Testnets—Avalanche Fuji and Celo Alfajores—and send messages from one chain to another. This tutorial is perfect for those new to cross-chain development and seeking hands-on experience with Wormhole's powerful toolkit. -**Header layout:** +By the end of this tutorial, you will have not only built a fully functioning cross-chain message sender and receiver using Solidity but also developed a comprehensive understanding of how to interact with the Wormhole relayer, manage cross-chain costs, and ensure your smart contracts are configured correctly on both source and target chains. -```typescript -const guardianSignatureLayout = [ - { name: 'guardianIndex', binary: 'uint', size: 1 }, - { name: 'signature', ...signatureItem }, -] as const satisfies Layout; +This tutorial assumes a basic understanding of Solidity and smart contract development. Before diving in, it may be helpful to review [the basics of Wormhole](/docs/protocol/introduction/){target=\_blank} to familiarize yourself with the protocol. -export const headerLayout = [ - { name: 'version', binary: 'uint', size: 1, custom: 1, omit: true }, - { name: 'guardianSet', ...guardianSetItem }, - { - name: 'signatures', - binary: 'array', - lengthSize: 1, - layout: guardianSignatureLayout, - }, -] as const satisfies Layout; -``` +## Wormhole Overview -The header defines metadata for validating and processing the VAA, such as the Guardian set index and signatures. Each signature is represented using the `signatureItem` layout, ensuring consistency and compatibility across different platforms. +We'll interact with two key Wormhole components: the [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} and the [Wormhole Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank}. The relayer handles cross-chain message delivery and ensures the message is accurately received on the target chain. This allows smart contracts to communicate across blockchains without developers worrying about the underlying complexity. -!!! note "Signature Standard Compliance" +Additionally, we'll rely on the Wormhole relayer to automatically determine cross-chain transaction costs and facilitate payments. This feature simplifies cross-chain development by allowing you to specify only the target chain and the message. The relayer handles the rest, ensuring that the message is transmitted with the appropriate fee. - The signature field uses the `signatureItem` layout, which is explicitly defined as 65 bytes. This layout is aligned with widely used standards such as EIP-2612 and Uniswap's Permit2, ensuring compatibility with cryptographic protocols and applications. +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -**Envelope layout:** +## Prerequisites -```typescript -export const envelopeLayout = [ - { name: 'timestamp', binary: 'uint', size: 4 }, - { name: 'nonce', binary: 'uint', size: 4 }, - { name: 'emitterChain', ...chainItem() }, - { name: 'emitterAddress', ...universalAddressItem }, - { name: 'sequence', ...sequenceItem }, - { name: 'consistencyLevel', binary: 'uint', size: 1 }, -] as const satisfies Layout; -``` +Before starting this tutorial, ensure you have the following: -The envelope encapsulates the VAA's core message data, including chain-specific information like the emitter address and sequence number. This structured layout ensures that the VAA can be securely transmitted across chains. +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for deploying contracts +- Testnet tokens for [Avalanche-Fuji](https://core.app/tools/testnet-faucet/?token=C){target=\_blank} and [Celo-Alfajores](https://faucet.celo.org/alfajores){target=\_blank} to cover gas fees +- Wallet private key -**Payload Layout:** +## Build Cross-Chain Messaging Contracts -The Payload contains the user-defined data specific to the application or protocol, such as a token transfer message, governance action, or other cross-chain operation. The layout of the payload is dynamic and depends on the payload type, identified by the `payloadLiteral` field. +In this section, we'll deploy two smart contracts: one to send a message from Avalanche Fuji and another to receive it on Celo Alfajores. The contracts interact with the Wormhole relayer to transmit messages across chains. -```typescript -const examplePayloadLayout = [ - { name: 'type', binary: 'uint', size: 1 }, - { name: 'data', binary: 'bytes', lengthSize: 2 }, -] as const satisfies Layout; -``` +At a high level, our contracts will: -This example demonstrates a payload containing: +1. Send a message from Avalanche to Celo using the Wormhole relayer +2. Receive and process the message on Celo, logging the content of the message - - A type field specifying the operation type (e.g., transfer or governance action) - - A data field that is length-prefixed and can store operation-specific information +Before diving into the deployment steps, let's first break down key parts of the contracts. -Dynamic payload layouts are selected at runtime using the `payloadLiteral` field, which maps to a predefined layout in the Wormhole SDK. +### Sender Contract: MessageSender -**Combined Base Layout:** +The `MessageSender` contract is responsible for quoting the cost of sending a message cross-chain and then sending that message. -The base VAA layout combines the header, envelope, and dynamically selected payload layout: +Key functions include: -```typescript -export const baseLayout = [...headerLayout, ...envelopeLayout] as const; + - **`quoteCrossChainCost`** - calculates the cost of delivering a message to the target chain using the Wormhole relayer + - **`sendMessage`** - encodes the message and sends it to the target chain and contract address using the Wormhole relayer + +Here's the core of the contract: + +```solidity +uint16 targetChain, + address targetAddress, + string memory message + ) external payable { + uint256 cost = quoteCrossChainCost(targetChain); + + require( + msg.value >= cost, + "Insufficient funds for cross-chain delivery" + ); + + wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(message, msg.sender), + 0, + GAS_LIMIT + ); + } ``` -At runtime, the payload layout is appended to the `baseLayout` to form the complete structure. +You can find the full code for the `MessageSender.sol` below. -#### Serializing VAA Data +??? code "MessageSender.sol" -The Wormhole SDK provides the [`serialize`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/functions.ts#L48-L54){target=\_blank} function to serialize a VAA message. This function combines the base layout (header and envelope) with the appropriate payload layout, ensuring the message’s format is correct for transmission across chains. + ```solidity + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; -```typescript -import { serialize } from '@wormhole-foundation/sdk-core/vaa/functions'; +import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeRelayer.sol"; -const vaaData = { - guardianSet: 1, - signatures: [{ guardianIndex: 0, signature: new Uint8Array(65).fill(0) }], - timestamp: 1633000000, - nonce: 42, - emitterChain: 2, // Ethereum - emitterAddress: new Uint8Array(32).fill(0), - sequence: BigInt(1), - consistencyLevel: 1, - payloadLiteral: 'SomePayloadType', - payload: { key: 'value' }, -}; +contract MessageSender { + IWormholeRelayer public wormholeRelayer; + uint256 constant GAS_LIMIT = 50000; -const serializedVAA = serialize(vaaData); -``` + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + } -???- note "How does it work?" + function quoteCrossChainCost( + uint16 targetChain + ) public view returns (uint256 cost) { + (cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); + } - Internally, the serialize function dynamically combines the `baseLayout` (header and envelope) with the payload layout defined by the `payloadLiteral`. The complete layout is then passed to the `serializeLayout` function, which converts the data into binary format. + function sendMessage( + uint16 targetChain, + address targetAddress, + string memory message + ) external payable { + uint256 cost = quoteCrossChainCost(targetChain); - ```typescript - const layout = [ - ...baseLayout, // Header and envelope layout - payloadLiteralToPayloadItemLayout(vaa.payloadLiteral), // Payload layout -] as const; + require( + msg.value >= cost, + "Insufficient funds for cross-chain delivery" + ); -return serializeLayout(layout, vaa as LayoutToType); - + wormholeRelayer.sendPayloadToEvm{value: cost}( + targetChain, + targetAddress, + abi.encode(message, msg.sender), + 0, + GAS_LIMIT + ); + } +} ``` -#### Deserializing VAA Data +### Receiver Contract: MessageReceiver -The Wormhole SDK provides the [`deserialize`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/functions.ts#L162-L200){target=\_blank} function to parse a VAA from its binary format back into a structured object. This function uses the `baseLayout` and payload discriminator logic to ensure the VAA is correctly interpreted. +The `MessageReceiver` contract handles incoming cross-chain messages. When a message arrives, it decodes the payload and logs the message content. It ensures that only authorized contracts can send and process messages, adding an extra layer of security in cross-chain communication. -```typescript -import { deserialize } from '@wormhole-foundation/sdk-core/vaa/functions'; +#### Emitter Validation and Registration -const serializedVAA = new Uint8Array([ - /* Serialized VAA binary data */ -]); +In cross-chain messaging, validating the sender is essential to prevent unauthorized contracts from sending messages. The `isRegisteredSender` modifier ensures that messages can only be processed if they come from the registered contract on the source chain. This guards against malicious messages and enhances security. -const vaaPayloadType = 'SomePayloadType'; // The payload type expected for this VAA -const deserializedVAA = deserialize(vaaPayloadType, serializedVAA); -``` +Key implementation details include: -???- note "How does it work?" + - **`registeredSender`** - stores the address of the registered sender contract + - **`setRegisteredSender`** - registers the sender's contract address on the source chain. It ensures that only registered contracts can send messages, preventing unauthorized senders + - **`isRegisteredSender`** - restricts the processing of messages to only those from registered senders, preventing unauthorized cross-chain communication - Internally, the `deserialize` function uses the `baseLayout` (header and envelope) to parse the main VAA structure. It then identifies the appropriate payload layout using the provided payload type or discriminator. +```solidity - ```typescript - const [header, envelopeOffset] = deserializeLayout(headerLayout, data, { - consumeAll: false, -}); - -const [envelope, payloadOffset] = deserializeLayout(envelopeLayout, data, { - offset: envelopeOffset, - consumeAll: false, -}); - -const [payloadLiteral, payload] = - typeof payloadDet === 'string' - ? [ - payloadDet as PayloadLiteral, - deserializePayload(payloadDet as PayloadLiteral, data, payloadOffset), - ] - : deserializePayload( - payloadDet as PayloadDiscriminator, - data, - payloadOffset - ); - -return { - ...header, - ...envelope, - payloadLiteral, - payload, -} satisfies VAA; - ``` - -### Registering Custom Payloads - -In the Wormhole SDK, payloads rely on layouts to define their binary structure, ensuring consistency and type safety across protocols. Custom payloads extend this functionality, allowing developers to handle protocol-specific features or unique use cases. - -To learn how to define and register payloads using layouts, refer to the [Building Protocols and Payloads](/docs/build/toolkit/typescript-sdk/protocols-payloads/){target=\_blank} page for a detailed guide. +require( + registeredSenders[sourceChain] == sourceAddress, + "Not registered sender" + ); + _; + } -## Common Pitfalls & Best Practices + function setRegisteredSender( + uint16 sourceChain, + bytes32 sourceAddress + ) public { + require( + msg.sender == registrationOwner, + "Not allowed to set registered sender" + ); + registeredSenders[sourceChain] = sourceAddress; + } +``` -When working with the Wormhole SDK layout system, it's important to be aware of a few common issues that can arise. Below are some pitfalls to avoid and best practices to ensure smooth integration. +#### Message Processing -### Pitfalls to Avoid +The `receiveWormholeMessages` is the core function that processes the received message. It checks that the Wormhole relayer sent the message, decodes the payload, and emits an event with the message content. It is essential to verify the message sender to prevent unauthorized messages. -#### Defining Sizes for Data Types +```solidity +bytes memory payload, + bytes[] memory, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 + ) public payable override isRegisteredSender(sourceChain, sourceAddress) { + require( + msg.sender == address(wormholeRelayer), + "Only the Wormhole relayer can call this function" + ); -When defining sizes for each data type, make sure to match the actual data length to the specified size to prevent serialization and deserialization errors: + // Decode the payload to extract the message + string memory message = abi.decode(payload, (string)); - - **`uint` and `int`** - the specified size must be large enough to accommodate the data value. For instance, storing a value greater than 255 in a single byte (`uint8`) will fail since it exceeds the byte’s capacity. Similarly, an undersized integer (e.g., specifying 2 bytes for a 4-byte integer) can lead to data loss or deserialization failure - - **`bytes`** - the data must match the specified byte length in the layout. For example, defining a field as 32 bytes (`size: 32`) requires the provided data to be exactly 32 bytes long; otherwise, serialization will fail + // Example use of sourceChain for logging + if (sourceChain != 0) { + emit SourceChainLogged(sourceChain); + } -```typescript -// Pitfall: Mismatch between the size of data and the defined size in the layout -{ name: 'orderSender', binary: 'bytes', size: 32 } -// If the provided data is not exactly 32 bytes, this will fail + // Emit an event with the received message + emit MessageReceived(message); + } ``` -#### Incorrectly Defined Arrays +You can find the full code for the `MessageReceiver.sol` below. -Arrays can be fixed-length or length-prefixed, so it’s important to define them correctly. Fixed-length arrays must match the specified length, while length-prefixed arrays need a `lengthSize` field. +??? code "MessageReceiver.sol" -```typescript -// Pitfall: Array length does not match the expected size -{ name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 } -``` + ```solidity + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; -### Best Practices +import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeRelayer.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeReceiver.sol"; -These best practices and common pitfalls can help prevent bugs and improve the reliability of your implementation when working with layouts in the Wormhole SDK. +contract MessageReceiver is IWormholeReceiver { + IWormholeRelayer public wormholeRelayer; + address public registrationOwner; -#### Reuse Predefined Layout Items + // Mapping to store registered senders for each chain + mapping(uint16 => bytes32) public registeredSenders; -Rather than defining sizes or types manually, reuse the predefined layout items provided by the Wormhole SDK. These items ensure consistent formatting and enforce strong typing. + event MessageReceived(string message); + event SourceChainLogged(uint16 sourceChain); -For instance, use the `chainItem` layout for chain IDs or `universalAddressItem` for blockchain addresses: + constructor(address _wormholeRelayer) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + registrationOwner = msg.sender; // Set contract deployer as the owner + } -```typescript -import { - chainItem, - universalAddressItem, -} from '@wormhole-foundation/sdk-core/layout-items'; + modifier isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress) { + require( + registeredSenders[sourceChain] == sourceAddress, + "Not registered sender" + ); + _; + } -const exampleLayout = [ - { name: 'sourceChain', ...chainItem() }, // Use predefined chain ID layout - { name: 'senderAddress', ...universalAddressItem }, // Use universal address layout -] as const; -``` + function setRegisteredSender( + uint16 sourceChain, + bytes32 sourceAddress + ) public { + require( + msg.sender == registrationOwner, + "Not allowed to set registered sender" + ); + registeredSenders[sourceChain] = sourceAddress; + } -By leveraging predefined layout items, you reduce redundancy, maintain consistency, and ensure compatibility with Wormhole’s standards. + // Update receiveWormholeMessages to include the source address check + function receiveWormholeMessages( + bytes memory payload, + bytes[] memory, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 + ) public payable override isRegisteredSender(sourceChain, sourceAddress) { + require( + msg.sender == address(wormholeRelayer), + "Only the Wormhole relayer can call this function" + ); -#### Use Class Instances + // Decode the payload to extract the message + string memory message = abi.decode(payload, (string)); -Whenever possible, convert deserialized data into higher-level class instances. This makes it easier to validate, manipulate, and interact with structured data. For example, the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/universalAddress.ts#L17-L59){target=\_blank} class ensures consistent address handling: + // Example use of sourceChain for logging + if (sourceChain != 0) { + emit SourceChainLogged(sourceChain); + } -```typescript -import { UniversalAddress } from '@wormhole-foundation/sdk-core'; + // Emit an event with the received message + emit MessageReceived(message); + } +} + ``` -const deserializedAddress = new UniversalAddress(someBinaryData); -``` +## Deploy Contracts -Focusing on reusing predefined layout items and converting deserialized data into higher-level abstractions can ensure a more robust and maintainable implementation. +This section will guide you through deploying the cross-chain messaging contracts on the Avalanche Fuji and Celo Alfajores Testnets. Follow these steps to get your contracts up and running. -#### Consistent Error Handling +### Deployment Tools +We use _Foundry_ to deploy our smart contracts. However, you can use any tool you're comfortable with, such as: -Always handle errors during both serialization and deserialization. Catching exceptions allows you to log or resolve issues gracefully when working with potentially corrupted or invalid data. + - [Remix](https://remix.ethereum.org/){target=\_blank} for a browser-based IDE + - [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started#installation){target=\_blank} for a more extensive JavaScript/TypeScript workflow + - [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for a CLI-focused experience with built-in scripting and testing features -```typescript -try { - const deserialized = deserializeLayout(fillLayout, data); -} catch (error) { - console.error('Deserialization failed:', error); -} -``` +The contracts and deployment steps remain the same regardless of your preferred tool. The key is to ensure you have the necessary Testnet funds and are deploying to the right networks. -#### Leverage Reusable Layouts +### Repository Setup -Creating reusable layouts for commonly repeated structures improves code maintainability and reduces duplication. These layouts can represent fields or combinations of fields frequently encountered in cross-chain communication, such as chain IDs, addresses, and signatures. +To get started with cross-chain messaging using Wormhole, first clone the [GitHub repository](https://github.com/wormhole-foundation/demo-wormhole-messaging){target=\_blank}. This repository includes everything you need to deploy, interact, and test the message flow between chains. -For example, define a reusable layout for chain IDs and addresses: +This demo focuses on using the scripts, so it's best to take a look at them, starting with `deploySender.ts`, `deployReceiver.ts`, and `sendMessage.ts`. -```typescript -const commonLayout = [ - { name: 'chainId', binary: 'uint', size: 2 }, - { name: 'address', binary: 'bytes', size: 32 }, -] as const satisfies Layout; +To configure the dependencies properly, run the following command: -// Reuse the common layout in different contexts -const exampleLayout = [ - ...commonLayout, - { name: 'sequence', binary: 'uint', size: 8 }, -]; +```bash +npm install ``` -By abstracting common elements into a single layout, you ensure consistency across different parts of your application and simplify future updates. +The repository includes: -## Performance Considerations +- Two Solidity contracts: -Efficient serialization and deserialization are crucial when handling large amounts of cross-chain data. Below are some strategies and best practices to ensure optimal performance when using Wormhole SDK layouts. + - **`MessageSender.sol`** - contract that sends the cross-chain message from Avalanche + - **`MessageReceiver.sol`** - contract that receives the cross-chain message on Celo -### Lazy Instantiation +- Deployment scripts located in the `script` directory: -Building a discriminator can be resource-intensive for complex or large datasets. The layout structures do not incur significant upfront costs, but deferring the creation of discriminators until needed can improve efficiency. + - **`deploySender.ts`** - deploys the `MessageSender` contract to Avalanche + - **`deployReceiver.ts`** - deploys the `MessageReceiver` contract to Celo + - **`sendMessage.ts`** - sends a message from Avalanche to Celo -```typescript -const lazyDiscriminator = lazyInstantiate(() => layoutDiscriminator(layouts)); -``` +- Configuration files and ABI JSON files for easy deployment and interaction: -This approach ensures that discriminators are only built when required, helping to optimize performance, especially for complex or conditional layouts. + - **`chains.json`** - configuration file that stores key information for the supported Testnets, including the Wormhole relayer addresses, RPC URLs, and chain IDs. You likely won't need to modify this file unless you're working with different networks -## Resources + - A dedicated `interfaces` directory inside the `src` folder for TypeScript type definitions: -For further learning and practical experience, explore the following resources: + - **`ChainsConfig.ts`** - defines the types for the `chains.json` configuration file + - **`DeployedContracts.ts`** - contains types for deployed contract addresses and related information + - **`MessageJsons.ts`** - includes types for ABI and bytecode JSONs used by the deployment scripts + - **`index.ts`** - serves as an export aggregator for the interfaces, simplifying imports in other files - - **Wormhole TypeScript SDK** - the [Wormhole SDK repository](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} contains the core implementation of layouts, including predefined layout items and utilities like `serializeLayout` and `deserializeLayout` +### Important Setup Steps - - **Layout tests repository** - for hands-on experimentation, check out this [layout package repository](https://github.com/nonergodic/layout){target=\_blank}, which provides examples and unit tests to help you better understand serialization, deserialization, and the strong typing mechanism. Running these tests locally is a great way to deepen your understanding of how layouts function in real-world scenarios ---- END CONTENT --- +1. **Add your private key** - create a `.env` file in the root of the project and add your private key: + + ```env + touch .env + ``` -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/vaas-protocols/ ---- BEGIN CONTENT --- ---- -title: VAAs and Protocols -description: Understand how VAAs enable cross-chain messaging and how to handle them using Wormhole's TypeScript and Solidity SDKs. -categories: Typescript-SDK ---- + Inside `.env`, add your private key in the following format: -# VAAs and Protocols + ```env + PRIVATE_KEY=INSERT_PRIVATE_KEY + ``` -## Introduction +2. **Compile the contracts** - ensure everything is set up correctly by compiling the contracts: -Wormhole's core functionality revolves around [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs), which are signed messages enabling secure and decentralized communication across chains. This guide focuses on their practical usage within the Wormhole ecosystem, specifically when working with protocol-specific messages in the [TypeScript](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and [Solidity](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} SDKs. + ```bash + forge build + ``` -For deeper insights into serialization, deserialization, and protocol design, refer to: - -- [Data Layouts](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank} for serialization concepts -- [Building Protocols and Payloads](/docs/build/toolkit/typescript-sdk/protocols-payloads/){target=\_blank} for designing custom protocol messages - -This guide will help you understand how to handle VAAs and protocol messages in off-chain and on-chain scenarios. - -## VAA Structure - -Understanding the structure of VAAs is fundamental to working with Wormhole's SDKs. Each section of the VAA—Header, Envelope, and Payload—serves a specific role: +The expected output should be similar to this: -| Section | Description | -|----------|----------------------------------------------------------------------------------------------------------| -| Header | Includes the version and guardian signature information required to verify the VAA | -| Envelope | Contains metadata about the emitted message, such as the emitter chain, emitter address, and timestamp | -| Payload | Represents the actual message, in raw bytes, without a length prefix | +
+forge build + > [⠒] Compiling... + > [⠰] Compiling 30 files with 0.8.23 + [⠔] Solc 0.8.23 finished in 2.29s +Compiler run successful! + +
-The VAA's body combines the Envelope and Payload. The Wormhole Guardians signed the core data and hashed (using `keccak256`) to generate the VAA's unique identifier. +### Deployment Process -When integrating protocols like Token Bridge or Wormhole Relayer: +Both deployment scripts, `deploySender.ts` and `deployReceiver.ts`, perform the following key tasks: -- The TypeScript SDK handles VAAs off-chain, focusing on deserialization, validation, and payload extraction before submission -- The Solidity SDK processes VAAs on-chain, using libraries like `VaaLib` to decode and execute protocol actions +1. **Load configuration and contract details** - each script begins by loading the necessary configuration details, such as the network's RPC URL and the contract's ABI and bytecode. This information is essential for deploying the contract to the correct blockchain network -## VAAs in Protocol Contexts + === "`chains.json`" -### How VAAs Enable Protocol-Specific Messaging + ```json + { + "chains": [ + { + "description": "Avalanche testnet fuji", + "chainId": 6, + "rpc": "https://api.avax-test.network/ext/bc/C/rpc", + "tokenBridge": "0x61E44E506Ca5659E6c0bba9b678586fA2d729756", + "wormholeRelayer": "0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB", + "wormhole": "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C" + }, + { + "description": "Celo Testnet", + "chainId": 14, + "rpc": "https://alfajores-forno.celo-testnet.org", + "tokenBridge": "0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153", + "wormholeRelayer": "0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84", + "wormhole": "0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56" + } + ] +} + ``` -VAAs are the backbone of Wormhole's cross-chain communication, encapsulating critical protocol payloads that drive actions on different blockchains. Each protocol—such as [Token Bridge](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/tokenBridge){target=\_blank}, [Wormhole Relayer](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/relayer){target=\_blank}, or [Circle CCTP](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/circleBridge){target=\_blank}—uses VAAs to securely transmit its messages across chains. + === "`deploySender.ts`" -Examples of mapping protocols to VAAs: + ```typescript + const chains: ChainsConfig = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) + ); -| Protocol | Payload Purpose | Example | -|-----------------|-----------------------------------------------------------|------------------------------------| -| Token Bridge | Transfers token data and metadata | Token transfer or redemption | -| Wormhole Relayer| Manages delivery instructions for messages across chains | Delivery fee or refund handling | -| Circle CCTP | Facilitates stablecoin mint-and-burn operations | Circle-issued stablecoin transfer | + // Get the Avalanche Fuji configuration + const avalancheChain = chains.chains.find((chain) => + chain.description.includes('Avalanche testnet') + ); + ``` -Each protocol integrates its payload format into the VAA structure, ensuring consistent message validation and execution across the ecosystem. + === "`deployReceiver.ts`" -### TypeScript SDK: Off-Chain Handling of VAAs + ```typescript + const chains: ChainsConfig = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) + ); -The TypeScript SDK is designed for off-chain operations like reading, validating, and manipulating VAAs before submitting them to a chain. Developers can easily deserialize VAAs to extract protocol payloads and prepare actions such as initiating token transfers or constructing delivery instructions. + // Get the Celo Testnet configuration + const celoChain = chains.chains.find((chain) => + chain.description.includes('Celo Testnet') + ); + ``` -In the example below, we use the real [`envelopeLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dd6bd2463264680597519285ff559f9e92e85ca7/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} from Wormhole's TS SDK to deserialize and extract essential information like the emitter chain, sequence, and [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank}: + !!! note + The `chains.json` file contains the configuration details for the Avalanche Fuji and Celo Alfajores Testnets. You can modify this file to add more networks if needed. For a complete list of contract addresses, visit the [reference page](/docs/products/reference/contract-addresses/){target=\_blank}. -```typescript -import { deserializeLayout } from '@wormhole-foundation/sdk-base'; -import { - universalAddressItem, - sequenceItem, -} from '@wormhole-foundation/core/layout-items/index.js'; +2. **Set up provider and wallet** - the scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction -export const envelopeLayout = [ - { name: 'timestamp', binary: 'uint', size: 4 }, - { name: 'nonce', binary: 'uint', size: 4 }, - { name: 'emitterChain', binary: 'uint', size: 2 }, - { name: 'emitterAddress', ...universalAddressItem }, - { name: 'sequence', ...sequenceItem }, - { name: 'consistencyLevel', binary: 'uint', size: 1 }, -] as const satisfies Layout; + === "`deploySender.ts`" -const encodedEnvelope = new Uint8Array([ - /* binary envelope data */ -]); -const deserializedEnvelope = deserializeLayout(envelopeLayout, encodedEnvelope); -``` + ```typescript + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + ``` -For more details, you can refer to the [parseVAA example](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/examples/src/parseVaa.ts){target=\_blank} in the Wormhole SDK repository. + === "`deployReceiver.ts`" -### Solidity SDK: On-Chain Handling of VAAs + ```typescript + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + ``` -The Solidity SDK enables on-chain processing of VAAs directly within smart contracts. This is essential for real-time validation, decoding, and execution of protocol-specific payloads. Developers can use libraries like [`VaaLib`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/e19013d08d1fdf5af9e6344c637e36a270422dd9/src/libraries/VaaLib.sol){target=\_blank} to parse the VAA header and payload, ensuring the message is authentic and consistent with Wormhole's validation. +3. **Deploy the contract** - the contract is deployed to the network specified in the configuration. Upon successful deployment, the contract address is returned, which is crucial for interacting with the contract later on -Below is an example of parsing an envelope on-chain using the Solidity SDK: + === "`deploySender.ts`" -```solidity -// SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.19; + ```typescript + avalancheChain.wormholeRelayer + ); + await senderContract.waitForDeployment(); + ``` -import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; + === "`deployReceiver.ts`" -contract EnvelopeParser { - using VaaLib for bytes; + ```typescript + celoChain.wormholeRelayer + ); + await receiverContract.waitForDeployment(); + ``` - function parseEnvelope( - bytes memory encodedVaa - ) - public - pure - returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel - ) - { - // Skip the header and decode the envelope - uint offset = VaaLib.skipVaaHeaderMemUnchecked(encodedVaa, 0); - return VaaLib.decodeVaaEnvelopeMemUnchecked(encodedVaa, offset); - } -} -``` ---- END CONTENT --- +4. **Register the `MessageSender` on the target chain** - after you deploy the `MessageReceiver` contract on the Celo Alfajores network, the sender contract address from Avalanche Fuji needs to be registered. This ensures that only messages from the registered `MessageSender` contract are processed -Doc-Content: https://wormhole.com/docs/build/toolkit/typescript-sdk/wormhole-sdk/ ---- BEGIN CONTENT --- ---- -title: Wormhole TS SDK -description: Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC. -categories: Typescript-SDK ---- + This additional step is essential to enforce emitter validation, preventing unauthorized senders from delivering messages to the `MessageReceiver` contract -# Wormhole TypeScript SDK + ```typescript + const avalancheSenderAddress = deployedContracts.avalanche?.MessageSender; + if (!avalancheSenderAddress) { + throw new Error('Avalanche MessageSender address not found.'); + } -## Introduction + // Define the source chain ID for Avalanche Fuji + const sourceChainId = 6; -The Wormhole TypeScript SDK is useful for interacting with the chains Wormhole supports and the [protocols](#protocols) built on top of Wormhole. This package bundles together functions, definitions, and constants that streamline the process of connecting chains and completing transfers using Wormhole. The SDK also offers targeted sub-packages for Wormhole-connected platforms, which allow you to add multichain support without creating outsized dependencies. + // Call setRegisteredSender on the MessageReceiver contract + const tx = await (receiverContract as any).setRegisteredSender( + sourceChainId, + ethers.zeroPadValue(avalancheSenderAddress, 32) + ); + await tx.wait(); + ``` -This section covers all you need to know about the functionality and ease of development offered through the Wormhole TypeScript SDK. Take a tour of the package to discover how it helps make integration easier. Learn more about how the SDK abstracts away complexities around concepts like platforms, contexts, and signers. Finally, you'll find guidance on usage, along with code examples, to show you how to use the tools of the SDK. +You can find the full code for the `deploySender.ts` and `deployReceiver.ts` below. +??? code "deploySender.ts" -
+ ```typescript + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import dotenv from 'dotenv'; +import { + ChainsConfig, + DeployedContracts, + MessageSenderJson, +} from './interfaces'; -- :octicons-download-16:{ .lg .middle } **Installation** +dotenv.config(); - --- +async function main(): Promise { + // Load the chain configuration from JSON + const chains: ChainsConfig = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) + ); - Find installation instructions for both the meta package and installing specific, individual packages + // Get the Avalanche Fuji configuration + const avalancheChain = chains.chains.find((chain) => + chain.description.includes('Avalanche testnet') + ); + if (!avalancheChain) { + throw new Error( + 'Avalanche testnet configuration not found in chains.json.' + ); + } - [:custom-arrow: Install the SDK](#installation) + // Set up the provider and wallet + const provider = new ethers.JsonRpcProvider(avalancheChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); -- :octicons-book-16:{ .lg .middle } **Concepts** + // Load the ABI and bytecode of the MessageSender contract + const messageSenderJson: MessageSenderJson = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), + 'utf8' + ) + ); - --- + const { abi, bytecode } = messageSenderJson; - Understand key concepts and how the SDK abstracts them away. Learn more about platforms, chain context, addresses, and signers + // Create a ContractFactory for MessageSender + const MessageSender = new ethers.ContractFactory(abi, bytecode, wallet); - [:custom-arrow: Explore concepts](#concepts) + // Deploy the contract using the Wormhole Relayer address for Avalanche Fuji + const senderContract = await MessageSender.deploy( + avalancheChain.wormholeRelayer + ); + await senderContract.waitForDeployment(); -- :octicons-file-code-16:{ .lg .middle } **Usage** + console.log('MessageSender deployed to:', senderContract.target); // `target` is the address in ethers.js v6 - --- + // Update the deployedContracts.json file + const deployedContractsPath = path.resolve( + __dirname, + '../deploy-config/deployedContracts.json' + ); + const deployedContracts: DeployedContracts = JSON.parse( + fs.readFileSync(deployedContractsPath, 'utf8') + ); - Guidance on using the SDK to add seamless interchain messaging to your application, including code examples + deployedContracts.avalanche = { + MessageSender: senderContract.target as any, + deployedAt: new Date().toISOString(), + }; - [:custom-arrow: Use the SDK](#usage) + fs.writeFileSync( + deployedContractsPath, + JSON.stringify(deployedContracts, null, 2) + ); +} -- :octicons-code-square-16:{ .lg .middle } **TSdoc for SDK** +main().catch((error) => { + console.error(error); + process.exit(1); +}); + + ``` - --- +??? code "deployReceiver.ts" - Review the TSdoc for the Wormhole TypeScript SDK for a detailed look at availabel methods, classes, interfaces, and definitions + ```typescript + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import dotenv from 'dotenv'; +import { + ChainsConfig, + DeployedContracts, + MessageReceiverJson, +} from './interfaces'; - [:custom-arrow: View the TSdoc on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank} +dotenv.config(); -
+async function main(): Promise { + // Load the chain configuration from the JSON file + const chains: ChainsConfig = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) + ); -!!! warning - This package is a work in progress. The interface may change, and there are likely bugs. Please [report](https://github.com/wormhole-foundation/connect-sdk/issues){target=\_blank} any issues you find. + // Get the Celo Testnet configuration + const celoChain = chains.chains.find((chain) => + chain.description.includes('Celo Testnet') + ); + if (!celoChain) { + throw new Error('Celo Testnet configuration not found.'); + } -## Installation + // Set up the provider and wallet + const provider = new ethers.JsonRpcProvider(celoChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + + // Load the ABI and bytecode of the MessageReceiver contract + const messageReceiverJson: MessageReceiverJson = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/MessageReceiver.sol/MessageReceiver.json' + ), + 'utf8' + ) + ); -### Basic + const { abi, bytecode } = messageReceiverJson; -To install the meta package using npm, run the following command in the root directory of your project: + // Create a ContractFactory for MessageReceiver + const MessageReceiver = new ethers.ContractFactory(abi, bytecode, wallet); -```bash -npm install @wormhole-foundation/sdk -``` + // Deploy the contract using the Wormhole Relayer address for Celo Testnet + const receiverContract = await MessageReceiver.deploy( + celoChain.wormholeRelayer + ); + await receiverContract.waitForDeployment(); -This package combines all the individual packages to make setup easier while allowing for tree shaking. + console.log('MessageReceiver deployed to:', receiverContract.target); // `target` is the contract address in ethers.js v6 -### Advanced + // Update the deployedContracts.json file + const deployedContractsPath = path.resolve( + __dirname, + '../deploy-config/deployedContracts.json' + ); + const deployedContracts: DeployedContracts = JSON.parse( + fs.readFileSync(deployedContractsPath, 'utf8') + ); -Alternatively, you can install a specific set of published packages individually: + // Retrieve the address of the MessageSender from the deployedContracts.json file + const avalancheSenderAddress = deployedContracts.avalanche?.MessageSender; + if (!avalancheSenderAddress) { + throw new Error('Avalanche MessageSender address not found.'); + } -??? interface "`sdk-base` - exposes constants" + // Define the source chain ID for Avalanche Fuji + const sourceChainId = 6; - ```sh - npm install @wormhole-foundation/sdk-base - ``` + // Call setRegisteredSender on the MessageReceiver contract + const tx = await (receiverContract as any).setRegisteredSender( + sourceChainId, + ethers.zeroPadValue(avalancheSenderAddress, 32) + ); + await tx.wait(); -??? interface "`sdk-definitions` - exposes contract interfaces, basic types, and VAA payload definitions" + console.log( + `Registered MessageSender (${avalancheSenderAddress}) for Avalanche chain (${sourceChainId})` + ); - ```sh - npm install @wormhole-foundation/sdk-definitions - ``` + deployedContracts.celo = { + MessageReceiver: receiverContract.target as any, + deployedAt: new Date().toISOString(), + }; -??? interface "`sdk-evm` - exposes EVM-specific utilities" + fs.writeFileSync( + deployedContractsPath, + JSON.stringify(deployedContracts, null, 2) + ); +} - ```sh - npm install @wormhole-foundation/sdk-evm +main().catch((error) => { + console.error(error); + process.exit(1); +}); + ``` -??? interface "`sdk-evm-tokenbridge` - exposes the EVM Token Bridge protocol client" +### Deploy the Sender Contract - ```sh - npm install @wormhole-foundation/sdk-evm-tokenbridge +The sender contract will handle quoting and sending messages cross-chain. + +1. Run the following command to deploy the sender contract: + + ```bash + npm run deploy:sender ``` -## Usage +2. Once deployed, the contract address will be displayed. You may check the contract on the [Avalanche Fuji Explorer](https://testnet.snowtrace.io/){target=\_blank} -Getting your integration started is simple. First, import Wormhole: +
+npm run deploy:sender + > wormhole-cross-chain@1.0.0 deploy:sender + > node script/deploySender.ts + MessageSender deployed to: 0xf5c474f335fFf617fA6FD04DCBb17E20ee0cEfb1 + +
-```ts -import { wormhole } from '@wormhole-foundation/sdk'; -import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; -import algorand from '@wormhole-foundation/sdk/algorand'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { getSigner } from './helpers/index.js'; +### Deploy the Receiver Contract -(async function () { - const wh = await wormhole('Testnet', [ - evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); +The receiver contract listens for cross-chain messages and logs them when received. - const ctx = wh.getChain('Solana'); +1. Deploy the receiver contract with this command: + + ```bash + npm run deploy:receiver + ``` - const rcv = wh.getChain('Algorand'); +2. After deployment, note down the contract address. You may check the contract on the [Celo Alfajores Explorer](https://alfajores.celoscan.io/){target=\_blank}. - const sender = await getSigner(ctx); - const receiver = await getSigner(rcv); - // Get a Token Bridge contract client on the source - const sndTb = await ctx.getTokenBridge(); +## Send a Cross-Chain Message - // Send the native token of the source chain - const tokenId = Wormhole.tokenId(ctx.chain, 'native'); +Now that both the sender and receiver contracts are deployed, let's move on to the next exciting step: sending a cross-chain message from Avalanche Fuji to Celo Alfajores. - // Bigint amount using `amount` module - const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); +In this example, we will use the `sendMessage.ts` script to transmit a message from the sender contract on Avalanche to the receiver contract on Celo. The script uses [Ethers.js](https://docs.ethers.org/v6/){target=\_blank} to interact with the deployed contracts, calculate the cross-chain cost dynamically, and handle the transaction. - // Create a transaction stream for transfers - const transfer = sndTb.transfer( - sender.address.address, - receiver.address, - tokenId.address, - amt - ); +Let's break down the script step by step. - // Sign and send the transaction - const txids = await signSendWait(ctx, transfer, sender.signer); - console.log('Sent: ', txids); +1. **Load configuration files** - // Get the Wormhole message ID from the transaction - const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); - console.log('Wormhole Messages: ', whm); + 1. **`chains.json`** - contains details about the supported Testnet chains, such as RPC URLs and relayer addresses + 2. **`deployedContracts.json`** - stores the addresses of the deployed sender and receiver contracts. This file is dynamically updated when contracts are deployed, but users can also manually add their own deployed contract addresses if needed - const vaa = await wh.getVaa( - // Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 + ```typescript + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) ); - // Now get the token bridge on the redeem side - const rcvTb = await rcv.getTokenBridge(); - - // Create a transaction stream for redeeming - const redeem = rcvTb.redeem(receiver.address.address, vaa!); + const deployedContracts: DeployedContracts = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/deployedContracts.json'), + 'utf8' + ) + ); + ``` - // Sign and send the transaction - const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); - console.log('Sent: ', rcvTxids); +2. **Configure the provider and signer** - the script first reads the chain configurations and extracts the contract addresses. One essential step in interacting with a blockchain is setting up a _provider_. A provider is your connection to the blockchain network. It allows your script to interact with the blockchain, retrieve data, and send transactions. In this case, we're using a JSON-RPC provider - // Now check if the transfer is completed according to - // the destination token bridge - const finished = await rcvTb.isTransferCompleted(vaa!); - console.log('Transfer completed: ', finished); -})(); -``` + Next, we configure the wallet, which will be used to sign transactions. The wallet is created using the private key and the provider. This ensures that all transactions sent from this wallet are broadcast to the Avalanche Fuji network: + + ```typescript + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); + ``` -Then, import each of the ecosystem [platforms](#platforms) that you wish to support: + After setting up the wallet, the script loads the ABI for the `MessageSender.sol` contract and creates an instance of it: -```ts -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -``` + ```typescript + fs.readFileSync( + path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), + 'utf8' + ) + ); + ``` +3. **Set up the message details** - the next part of the script defines the target chain (Celo) and the target address (the receiver contract on Celo): -To make the [platform](#platforms) modules available for use, pass them to the Wormhole constructor: + ```typescript + const targetAddress = deployedContracts.celo.MessageReceiver; + ``` -```ts -evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); -``` + You can customize the message that will be sent across chains: -With a configured Wormhole object, you can do things like parse addresses for the provided platforms, get a [`ChainContext`](#chain-context) object, or fetch VAAs. + ```typescript + + ``` -```ts +4. **Estimate cross-chain cost** - before sending the message, we dynamically calculate the cross-chain cost using the `quoteCrossChainCost` function: -``` + ```typescript + + ``` -You can retrieve a VAA as follows. In this example, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will vary by network. + This ensures that the transaction includes enough funds to cover the gas fees for the cross-chain message. -```ts -// Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 +5. **Send a message** - with everything set up, the message is sent using the `sendMessage` function: + + ```typescript + targetChain, + targetAddress, + message, + { + value: txCost, + } ); -``` + ``` -??? code "View the complete script" - ```ts - import { wormhole } from '@wormhole-foundation/sdk'; + After sending, the script waits for the transaction to be confirmed: -import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; -import algorand from '@wormhole-foundation/sdk/algorand'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { getSigner } from './helpers/index.js'; + ```typescript + + ``` -(async function () { - const wh = await wormhole('Testnet', [ - evm, - solana, - aptos, - algorand, - cosmwasm, - sui, - ]); +6. **Run the script** - to send the message, run the following command: - const ctx = wh.getChain('Solana'); + ```bash + npm run send:message + ``` - const rcv = wh.getChain('Algorand'); +If everything is set up correctly, the message will be sent from the Avalanche Fuji Testnet to the Celo Alfajores Testnet. You can monitor the transaction and verify that the message was received on Celo using the [Wormhole Explorer](https://wormholescan.io/#/?network=TESTNET){target=\_blank}. - const sender = await getSigner(ctx); - const receiver = await getSigner(rcv); +The console should output something similar to this: - // Get a Token Bridge contract client on the source - const sndTb = await ctx.getTokenBridge(); +
+npm run send:message + > wormhole-cross-chain@1.0.0 send:message + > node script/sendMessage.ts +Sender Contract Address: 0xD720BFF42a0960cfF1118454A907a44dB358f2b1 +Receiver Contract Address: 0x692550997C252cC5044742D1A2BD91E4f4b46D39 +... +Transaction sent, waiting for confirmation... +... +Message sent! Transaction hash: + 0x9d359a66ba42baced80062229c0b02b4f523fe304aff3473dcf53117aee13fb6 +You may see the transaction status on the Wormhole Explorer: + https://wormholescan.io/#/tx/0x9d359a66ba42baced80062229c0b02b4f523fe304aff3473dcf53117aee13fb6?network=TESTNET + +
- // Send the native token of the source chain - const tokenId = Wormhole.tokenId(ctx.chain, 'native'); +You can find the full code for the `sendMessage.ts` below. - // Bigint amount using `amount` module - const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); +??? code "sendMessage.ts" - // Create a transaction stream for transfers - const transfer = sndTb.transfer( - sender.address.address, - receiver.address, - tokenId.address, - amt + ```solidity + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import dotenv from 'dotenv'; +import { ChainsConfig, DeployedContracts } from './interfaces'; + +dotenv.config(); + +async function main(): Promise { + // Load the chain configuration and deployed contract addresses + const chains: ChainsConfig = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/chains.json'), + 'utf8' + ) ); - // Sign and send the transaction - const txids = await signSendWait(ctx, transfer, sender.signer); - console.log('Sent: ', txids); + const deployedContracts: DeployedContracts = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../deploy-config/deployedContracts.json'), + 'utf8' + ) + ); - // Get the Wormhole message ID from the transaction - const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); - console.log('Wormhole Messages: ', whm); + console.log( + 'Sender Contract Address: ', + deployedContracts.avalanche.MessageSender + ); + console.log( + 'Receiver Contract Address: ', + deployedContracts.celo.MessageReceiver + ); + console.log('...'); - const vaa = await wh.getVaa( - // Wormhole Message ID - whm!, - // Protocol:Payload name to use for decoding the VAA payload - 'TokenBridge:Transfer', - // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available - 60_000 + // Get the Avalanche Fuji configuration + const avalancheChain = chains.chains.find((chain) => + chain.description.includes('Avalanche testnet') ); - // Now get the token bridge on the redeem side - const rcvTb = await rcv.getTokenBridge(); + if (!avalancheChain) { + throw new Error( + 'Avalanche testnet configuration not found in chains.json.' + ); + } - // Create a transaction stream for redeeming - const redeem = rcvTb.redeem(receiver.address.address, vaa!); + // Set up the provider and wallet + const provider = new ethers.JsonRpcProvider(avalancheChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - // Sign and send the transaction - const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); - console.log('Sent: ', rcvTxids); + // Load the ABI of the MessageSender contract + const messageSenderJson = JSON.parse( + fs.readFileSync( + path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), + 'utf8' + ) + ); - // Now check if the transfer is completed according to - // the destination token bridge - const finished = await rcvTb.isTransferCompleted(vaa!); - console.log('Transfer completed: ', finished); -})(); - ``` + const abi = messageSenderJson.abi; -Optionally, you can override the default configuration with a partial `WormholeConfig` object to specify particular fields, such as a different RPC endpoint. + // Create a contract instance for MessageSender + const MessageSender = new ethers.Contract( + deployedContracts.avalanche.MessageSender, // Automatically use the deployed address + abi, + wallet + ); -```ts -const wh = await wormhole('Testnet', [solana], { - chains: { - Solana: { - contracts: { - coreBridge: '11111111111111111111111111111', - }, - rpc: 'https://api.devnet.solana.com', - }, - }, -}); -``` + // Define the target chain and target address (the Celo receiver contract) + const targetChain = 14; // Wormhole chain ID for Celo Alfajores + const targetAddress = deployedContracts.celo.MessageReceiver; -??? code "View the complete script" - ```ts - import { wormhole } from '@wormhole-foundation/sdk'; -import solana from '@wormhole-foundation/sdk/solana'; -(async function () { - const wh = await wormhole('Testnet', [solana], { - chains: { - Solana: { - contracts: { - coreBridge: '11111111111111111111111111111', - }, - rpc: 'https://api.devnet.solana.com', - }, - }, - }); - console.log(wh.config.chains.Solana); -})(); - ``` + // The message you want to send + const message = 'Hello from Avalanche to Celo!'; -## Concepts + // Dynamically quote the cross-chain cost + const txCost = await MessageSender.quoteCrossChainCost(targetChain); -Understanding several higher-level Wormhole concepts and how the SDK abstracts them away will help you use the tools most effectively. The following sections will introduce and discuss the concepts of platforms, chain contexts, addresses, signers, and protocols, how they are used in the Wormhole context, and how the SDK helps ease development in each conceptual area. + // Send the message (make sure to send enough gas in the transaction) + const tx = await MessageSender.sendMessage( + targetChain, + targetAddress, + message, + { + value: txCost, + } + ); -### Platforms + console.log('Transaction sent, waiting for confirmation...'); + await tx.wait(); + console.log('...'); -While every chain has unique attributes, chains from the same platform typically have standard functionalities they share. The SDK includes `Platform` modules, which create a standardized interface for interacting with the chains of a supported platform. The contents of a module vary by platform but can include: + console.log('Message sent! Transaction hash:', tx.hash); + console.log( + `You may see the transaction status on the Wormhole Explorer: https://wormholescan.io/#/tx/${tx.hash}?network=TESTNET` + ); +} -- Protocols, such as [Wormhole core](#wormhole-core), preconfigured to suit the selected platform -- Definitions and configurations for types, signers, addresses, and chains -- Helpers configured for dealing with unsigned transactions on the selected platform +main().catch((error) => { + console.error(error); + process.exit(1); +}); + + ``` -These modules also import and expose essential functions and define types or constants from the chain's native ecosystem to reduce the dependencies needed to interact with a chain using Wormhole. Rather than installing the entire native package for each desired platform, you can install a targeted package of standardized functions and definitions essential to connecting with Wormhole, keeping project dependencies as slim as possible. +## Conclusion +You're now fully equipped to build cross-chain contracts using the Wormhole protocol! With this tutorial, you've learned how to: -Wormhole currently supports the following platforms: +- Deploy sender and receiver contracts on different Testnets +- Send a cross-chain message from one blockchain to another +- Monitor the status of your cross-chain transactions using the Wormhole Explorer and Wormhole-Solidity-SDK +--- END CONTENT --- -- EVM -- Solana -- Cosmos -- Sui -- Aptos -- Algorand +Doc-Content: https://wormhole.com/docs/products/messaging/tutorials/cross-chain-token-contracts/ +--- BEGIN CONTENT --- +--- +title: Cross-Chain Token Transfers +description: Learn how to create cross-chain token transfers using Wormhole's Solidity SDK. Build and deploy smart contracts to send tokens from one blockchain to another. +--- -See the [Platforms folder of the TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms){target=\_blank} for an up-to-date list of the platforms supported by the Wormhole TypeScript SDK. +# Create Cross-Chain Token Transfer Contracts -### Chain Context +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank} -The `definitions` package of the SDK includes the `ChainContext` class, which creates an interface for working with connected chains in a standardized way. This class contains the network, chain, and platform configurations for connected chains and cached RPC and protocol clients. The `ChainContext` class also exposes chain-specific methods and utilities. Much of the functionality comes from the `Platform` methods but some specific chains may have overridden methods via the context. This is also where the `Network`, `Chain`, and `Platform` type parameters which are used throughout the package are defined. +## Introduction -```ts -const srcChain = wh.getChain(senderAddress.chain); -const dstChain = wh.getChain(receiverAddress.chain); +In this tutorial, you'll learn how to create a simple cross-chain token transfer system using the Wormhole protocol via the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. We'll guide you through building and deploying smart contracts that enable seamless token transfers of IERC-20 tokens between blockchains. Whether you're a developer looking to explore cross-chain applications or just interested in the Wormhole protocol, this guide will help you understand the fundamentals. -const tb = await srcChain.getTokenBridge(); // => TokenBridge<'Evm'> -srcChain.getRpcClient(); // => RpcClient<'Evm'> -``` +By the end of this tutorial, you'll have a working cross-chain token transfer system built with the powerful tools provided by the Wormhole Solidity SDK, which you can further customize and integrate into your projects. -### Addresses +## Prerequisites -The SDK uses the `UniversalAddress` class to implement the `Address` interface, which all address types must implement. Addresses from various networks are parsed into their byte representation and modified as needed to ensure they are exactly 32 bytes long. Each platform also has an address type that understands the native address formats, referred to as `NativeAddress.` These abstractions allow you to work with addresses consistently regardless of the underlying chain. +Before you begin, ensure you have the following: -```ts -// It's possible to convert a string address to its Native address -const ethAddr: NativeAddress<'Evm'> = toNative('Ethereum', '0xbeef...'); +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for deploying contracts +- Testnet tokens for [Avalanche-Fuji](https://core.app/tools/testnet-faucet/?token=C){target=\_blank} and [Celo-Alfajores](https://faucet.celo.org/alfajores){target=\_blank} to cover gas fees +- [USDC Testnet](https://faucet.circle.com/){target=\_blank} tokens on Avalanche-Fuji or/and Celo-Alfajores for cross-chain transfer +- Wallet private key -// A common type in the SDK is the `ChainAddress` which provides -// the additional context of the `Chain` this address is relevant for -const senderAddress: ChainAddress = Wormhole.chainAddress( - 'Ethereum', - '0xbeef...' -); -const receiverAddress: ChainAddress = Wormhole.chainAddress( - 'Solana', - 'Sol1111...' -); +## Valid Tokens for Transfer -// Convert the ChainAddress back to its canonical string address format -const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' +It's important to note that this tutorial leverages [Wormhole's TokenBridge](https://github.com/wormhole-foundation/wormhole/blob/6130bbb6f456b42b789a71f7ea2fd049d632d2fb/ethereum/contracts/bridge/TokenBridge.sol){target=\_blank} to transfer tokens between chains. So, the tokens you'd like to transfer must have an attestation on the `TokenBridge` contract of the target blockchain. -// Or if the ethAddr above is for an emitter and you need the UniversalAddress -const emitterAddr = ethAddr.toUniversalAddress().toString(); -``` +To simplify this process, we've included a tool for verifying if a token has an attestation on the target chain. This tool uses the [`wrappedAsset`](https://github.com/wormhole-foundation/wormhole/blob/6130bbb6f456b42b789a71f7ea2fd049d632d2fb/ethereum/contracts/bridge/BridgeGetters.sol#L50-L52){target=\_blank} function from the `TokenBridge` contract. If the token has an attestation, the `wrappedAsset` function returns the address of the wrapped token on the target chain; otherwise, it returns the zero address. -### Tokens +???- tip "Check Token Attestation" + 1. Clone the [repository](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank} and navigate to the project directory: + ```bash + git clone https://github.com/wormhole-foundation/demo-cross-chain-token-transfer.git + cd cross-chain-token-transfers + ``` + 2. Install the dependencies: + ```bash + npm install + ``` + + 3. Run the script to check token attestation: + ```bash + npm run verify + ``` -Similar to the `ChainAddress` type, the `TokenId` type provides the chain and address of a given token. The following snippet introduces `TokenId`, a way to uniquely identify any token, whether it's a standard token or a blockchain's native currency (like ETH for Ethereum). + 4. Follow the prompts: -Wormhole uses their contract address to create a `TokenId` for standard tokens. For native currencies, Wormhole uses the keyword `native` instead of an address. This makes it easy to work with any type of token consistently. + 1. Enter the RPC URL of the target chain + 2. Enter the `TokenBridge` contract address on the target chain + 3. Enter the token contract address on the source chain + 4. Enter the source chain ID -Finally, the snippet demonstrates how to convert a `TokenId` back into a regular address format when needed. + 5. The expected output when the token has an attestation: + +
+npm run verify + > cross-chain-token-transfer@1.0.0 verify + > npx ts-node script/check-attestation.ts + + Enter the TARGET chain RPC URL: https://alfajores-forno.celo-testnet.org + Enter the Token Bridge contract address on the TARGET chain: 0x05...E153 + Enter the token contract address on the SOURCE chain: 0x54...bc65 + Enter the SOURCE chain ID: 6 + The token is attested on the target chain. Wrapped token address: 0xDDB349c976cA2C873644F21f594767Eb5390C831 + +
+ + Using this tool ensures that you only attempt to transfer tokens with verified attestations, avoiding any potential issues during the cross-chain transfer process. -```ts -const sourceToken: TokenId = Wormhole.tokenId('Ethereum', '0xbeef...'); +## Project Setup -const gasToken: TokenId = Wormhole.tokenId('Ethereum', 'native'); +Let's start by initializing a new Foundry project. This will set up a basic structure for our smart contracts. -const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' -``` +1. Open your terminal and run the following command to initialize a new Foundry project: + + ```bash + forge init cross-chain-token-transfers + ``` -### Signers + This will create a new directory named `cross-chain-token-transfers` with a basic project structure. This also initializes a new `git` repository. -Certain methods of signing transactions require a `Signer` interface in the SDK. Depending on the specific requirements, this interface can be fulfilled by either a `SignOnlySigner` or a `SignAndSendSigner`. A signer can be created by wrapping an offline or web wallet. +2. Navigate into the newly created project directory: -A `SignOnlySigner` is used when the signer isn't connected to the network or prefers not to broadcast transactions themselves. It accepts an array of unsigned transactions and returns an array of signed and serialized transactions. Before signing, the transactions may be inspected or altered. It's important to note that the serialization process is chain-specific. Refer to the testing signers (e.g., [EVM](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/evm/src/signer.ts){target=\_blank} or [Solana](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/solana/src/signer.ts){target=\_blank}) for an example of how to implement a signer for a specific chain or platform. + ```bash + cd cross-chain-token-transfers + ``` -Conversely, a `SignAndSendSigner` is appropriate when the signer is connected to the network and intends to broadcast the transactions. This type of signer also accepts an array of unsigned transactions but returns an array of transaction IDs corresponding to the order of the unsigned transactions. +3. Install the Wormhole Solidity SDK: -```ts -export type Signer = SignOnlySigner | SignAndSendSigner; + ```bash + forge install wormhole-foundation/wormhole-solidity-sdk + ``` -export interface SignOnlySigner { - chain(): ChainName; - address(): string; - // Accept an array of unsigned transactions and return - // an array of signed and serialized transactions. - // The transactions may be inspected or altered before - // signing. - sign(tx: UnsignedTransaction[]): Promise; -} + To ease development, we'll use the Wormhole Solidity SDK, which provides useful helpers for cross-chain development. + This SDK includes the `TokenSender` and `TokenReceiver` abstract classes, which simplify sending and receiving tokens across chains. -export interface SignAndSendSigner { - chain(): ChainName; - address(): string; - // Accept an array of unsigned transactions and return - // an array of transaction ids in the same order as the - // unsignedTransactions array. - signAndSend(tx: UnsignedTransaction[]): Promise; -} -``` +## Build Cross-Chain Contracts -#### Set Up a Signer with Ethers.js +In this section, we'll build two smart contracts to send tokens from a source chain and receive them on a target chain. These contracts will interact with the Wormhole protocol to facilitate secure and seamless cross-chain token transfers. -To sign transactions programmatically with the Wormhole SDK, you can use Ethers.js to manage private keys and handle signing. Here's an example of setting up a signer using Ethers.js: +At a high level, our contracts will: -```javascript -import { ethers } from 'ethers'; +1. Send tokens from one blockchain to another using the Wormhole protocol +2. Receive and process the tokens on the target chain, ensuring they are correctly transferred to the intended recipient -// Update the following variables -const rpcUrl = 'INSERT_RPC_URL'; -const privateKey = 'INSERT_PRIVATE_KEY'; -const toAddress = 'INSERT_RECIPIENT_ADDRESS'; +Before diving into the contract implementation steps, let’s first break down the key parts of the contracts. -// Set up a provider and signer -const provider = new ethers.JsonRpcProvider(rpcUrl); -const signer = new ethers.Wallet(privateKey, provider); +### Sender Contract: CrossChainSender -// Example: Signing and sending a transaction -async function sendTransaction() { - const tx = { - to: toAddress, - value: ethers.parseUnits('0.1'), // Sending 0.1 ETH - gasPrice: await provider.getGasPrice(), - gasLimit: ethers.toBeHex(21000), - }; +The `CrossChainSender` contract calculates the cost of sending tokens across chains and then facilitates the actual token transfer. - const transaction = await signer.sendTransaction(tx); - console.log('Transaction hash:', transaction.hash); -} -sendTransaction(); -``` +Let's start writing the `CrossChainSender` contract: - - **`provider`** - responsible for connecting to the Ethereum network (or any EVM-compatible network). It acts as a bridge between your application and the blockchain, allowing you to fetch data, check the state of the blockchain, and submit transactions +1. Create a new file named `CrossChainSender.sol` in the `/src` directory: + + ```bash + touch src/CrossChainSender.sol + ``` - - **`signer`** - represents the account that will sign the transaction. In this case, you’re creating a signer using the private key associated with the account. The signer is responsible for authorizing transactions by digitally signing them with the private key +2. Open the file. First, we'll start with the imports and the contract setup: - - **`Wallet`** - combines both the provider (for blockchain interaction) and the signer (for transaction authorization), allowing you to sign and send transactions programmatically + ```solidity + pragma solidity ^0.8.13; -These components work together to create, sign, and submit a transaction to the blockchain. +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -???- tip "Managing Private Keys Securely" - Handling private keys is unavoidable, so it’s crucial to manage them securely. Here are some best practices: +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; - - **Use environment variables** - avoid hardcoding private keys in your code. Use environment variables or secret management tools to inject private keys securely - - **Hardware wallets** - for production environments, consider integrating hardware wallets to keep private keys secure while allowing programmatic access through the SDK + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + ``` -### Protocols + This sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. -While Wormhole is a Generic Message Passing (GMP) protocol, several protocols have been built to provide specific functionality. If available, each protocol will have a platform-specific implementation. These implementations provide methods to generate transactions or read state from the contract on-chain. + With the contract structure in place, define the following functions within its body to enable multichain token transfers. -#### Wormhole Core +3. Next, let's add a function that estimates the cost of sending tokens across chains: -The core protocol underlies all Wormhole activity. This protocol is responsible for emitting the message containing the information necessary to perform bridging, including the [emitter address](https://docs.wormhole.com/wormhole/reference/glossary#emitter){target=\_blank}, the [sequence number](https://docs.wormhole.com/wormhole/reference/glossary#sequence){target=\_blank} for the message, and the payload of the message itself. + ```solidity + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); -The following example demonstrates sending and verifying a message using the Wormhole Core protocol on Solana. + cost = deliveryCost + wormhole.messageFee(); + } + ``` -First, initialize a Wormhole instance for the Testnet environment, specifically for the Solana chain. Then, obtain a signer and its associated address, which will be used to sign transactions. + This function, `quoteCrossChainDeposit`, helps calculate the cost of transferring tokens to a different chain. It factors in the delivery cost and the cost of publishing a message via the Wormhole protocol. -Next, get a reference to the core messaging bridge, which is the main interface for interacting with Wormhole's cross-chain messaging capabilities. -The code then prepares a message for publication. This message includes: +4. Finally, we'll add the function that sends the tokens across chains: -- The sender's address -- The message payload (in this case, the encoded string `lol`) -- A nonce (set to `0` here, but can be any user-defined value to uniquely identify the message) -- A [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} (set to `0`, which determines the finality requirements for the message) + ```solidity + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); -After preparing the message, the next steps are to generate, sign, and send the transaction or transactions required to publish the message on the Solana blockchain. Once the transaction is confirmed, the Wormhole message ID is extracted from the transaction logs. This ID is crucial for tracking the message across chains. + IERC20(token).transferFrom(msg.sender, address(this), amount); -The code then waits for the Wormhole network to process and sign the message, turning it into a Verified Action Approval (VAA). This VAA is retrieved in a `Uint8Array` format, with a timeout of 60 seconds. + bytes memory payload = abi.encode(recipient); -Lastly, the code will demonstrate how to verify the message on the receiving end. A verification transaction is prepared using the original sender's address and the VAA, and finally, this transaction is signed and sent. + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } + ``` -???+ code "View the complete script" - ```ts - import { encoding, signSendWait, wormhole } from '@wormhole-foundation/sdk'; -import { getSigner } from './helpers/index.js'; -import solana from '@wormhole-foundation/sdk/solana'; -import evm from '@wormhole-foundation/sdk/evm'; + This `sendCrossChainDeposit` function is where the actual token transfer happens. It sends the tokens to the recipient on the target chain using the Wormhole protocol. -(async function () { - const wh = await wormhole('Testnet', [solana, evm]); +Here’s a breakdown of what happens in each step of the `sendCrossChainDeposit` function: - const chain = wh.getChain('Avalanche'); - const { signer, address } = await getSigner(chain); +1. **Cost calculation** - the function starts by calculating the cost of the cross-chain transfer using `quoteCrossChainDeposit`(`targetChain`). This cost includes both the delivery fee and the Wormhole message fee. The `sendCrossChainDeposit` function then checks that the user has sent the correct amount of Ether to cover this cost (`msg.value`) - // Get a reference to the core messaging bridge - const coreBridge = await chain.getWormholeCore(); +2. **Token transfer to contract** - the next step is to transfer the specified amount of tokens from the user to the contract itself using `IERC-20(token).transferFrom(msg.sender, address(this), amount)`. This ensures that the contract has custody of the tokens before initiating the cross-chain transfer - // Generate transactions, sign and send them - const publishTxs = coreBridge.publishMessage( - // Address of sender (emitter in VAA) - address.address, - // Message to send (payload in VAA) - encoding.bytes.encode('lol'), - // Nonce (user defined, no requirement for a specific value, useful to provide a unique identifier for the message) - 0, - // ConsistencyLevel (ie finality of the message, see wormhole docs for more) - 0 - ); - // Send the transaction(s) to publish the message - const txids = await signSendWait(chain, publishTxs, signer); +3. **Payload encoding** - The recipient's address on the target chain is encoded into a payload using `abi.encode(recipient)`. This payload will be sent along with the token transfer, so the target contract knows who should receive the tokens on the destination chain - // Take the last txid in case multiple were sent - // The last one should be the one containing the relevant - // event or log info - const txid = txids[txids.length - 1]; +4. **Cross-chain transfer** - the `sendTokenWithPayloadToEvm` function is called to initiate the cross-chain token transfer. This function: + - Specifies the `targetChain` (the Wormhole chain ID of the destination blockchain). + - Sends the `targetReceiver` contract address on the target chain that will receive the tokens. + - Attaches the payload containing the recipient's address. + - Sets the `GAS_LIMIT` for the transaction. + - Passes the token `address` and `amount` to transfer. - // Grab the wormhole message id from the transaction logs or storage - const [whm] = await chain.parseTransaction(txid!.txid); + This triggers the Wormhole protocol to handle the cross-chain messaging and token transfer, ensuring the tokens and payload reach the correct destination on the target chain. - // Wait for the vaa to be signed and available with a timeout - const vaa = await wh.getVaa(whm!, 'Uint8Array', 60_000); - console.log(vaa); +You can find the complete code for the `CrossChainSender.sol` below. - // Note: calling verifyMessage manually is typically not a useful thing to do - // As the VAA is typically submitted to the counterpart contract for - // A given protocol and the counterpart contract will verify the VAA - // This is simply for demo purposes - const verifyTxs = coreBridge.verifyMessage(address.address, vaa!); - console.log(await signSendWait(chain, verifyTxs, signer)); -})(); - ``` +??? code "MessageSender.sol" -The payload contains the information necessary to perform whatever action is required based on the protocol that uses it. + ```solidity + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; -#### Token Bridge +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -The most familiar protocol built on Wormhole is the Token Bridge. Every chain has a `TokenBridge` protocol client that provides a consistent interface for interacting with the Token Bridge, which includes methods to generate the transactions required to transfer tokens and methods to generate and redeem attestations. `WormholeTransfer` abstractions are the recommended way to interact with these protocols, but it is possible to use them directly. +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; -```ts -import { signSendWait } from '@wormhole-foundation/sdk'; + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} -const tb = await srcChain.getTokenBridge(); + // Function to get the estimated cost for cross-chain deposit + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); -const token = '0xdeadbeef...'; -const txGenerator = tb.createAttestation(token); -const txids = await signSendWait(srcChain, txGenerator, src.signer); -``` + cost = deliveryCost + wormhole.messageFee(); + } -Supported protocols are defined in the [definitions module](https://github.com/wormhole-foundation/connect-sdk/tree/main/core/definitions/src/protocols){target=\_blank}. + // Function to send tokens and payload across chains + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); -## Transfers + IERC20(token).transferFrom(msg.sender, address(this), amount); -While using the [`ChainContext`](#chain-context) and [`Protocol`](#protocols) clients directly is possible, the SDK provides some helpful abstractions for transferring tokens. + bytes memory payload = abi.encode(recipient); -The `WormholeTransfer` interface provides a convenient abstraction to encapsulate the steps involved in a cross-chain transfer. + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -### Token Transfers +### Receiver Contract: CrossChainReceiver -Performing a token transfer is trivial for any source and destination chains. You can create a new `Wormhole` object to make objects like `TokenTransfer` and `CircleTransfer`, to transfer tokens between chains. +The `CrossChainReceiver` contract is designed to handle the receipt of tokens and payloads from another blockchain. It ensures that the tokens are correctly transferred to the designated recipient on the receiving chain. -The following example demonstrates the process of initiating and completing a token transfer. It starts by creating a `TokenTransfer` object, which tracks the transfer's state throughout its lifecycle. The code then obtains a quote for the transfer, ensuring the amount is sufficient to cover fees and any requested native gas. +Let's start writing the `CrossChainReceiver` contract: -The transfer process is divided into three main steps: +1. Create a new file named `CrossChainReceiver.sol` in the `/src` directory: -1. Initiating the transfer on the source chain -2. Waiting for the transfer to be attested (if not automatic) -3. Completing the transfer on the destination chain + ```bash + touch src/CrossChainReceiver.sol + ``` -For automatic transfers, the process ends after initiation. The code waits for the transfer to be attested for manual transfers and then completes it on the destination chain. +2. Open the file. First, we'll start with the imports and the contract setup: -```ts -const xfer = await wh.tokenTransfer( - route.token, - route.amount, - route.source.address, - route.destination.address, - route.delivery?.automatic ?? false, - route.payload, - route.delivery?.nativeGas - ); + ```solidity + pragma solidity ^0.8.13; - const quote = await TokenTransfer.quoteTransfer( - wh, - route.source.chain, - route.destination.chain, - xfer.transfer - ); - console.log(quote); +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - if (xfer.transfer.automatic && quote.destinationToken.amount < 0) - throw 'The amount requested is too low to cover the fee and any native gas requested.'; +contract CrossChainReceiver is TokenReceiver { + // The Wormhole relayer and registeredSenders are inherited from the Base.sol contract - // 1) Submit the transactions to the source chain, passing a signer to sign any txns - console.log('Starting transfer'); - const srcTxids = await xfer.initiateTransfer(route.source.signer); - console.log(`Started transfer: `, srcTxids); + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} + + ``` - // If automatic, we're done - if (route.delivery?.automatic) return xfer; + Similar to the `CrossChainSender` contract, this sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. - // 2) Wait for the VAA to be signed and ready (not required for auto transfer) - console.log('Getting Attestation'); - const attestIds = await xfer.fetchAttestation(60_000); - console.log(`Got Attestation: `, attestIds); +3. Next, let's add a function inside the contract to handle receiving the payload and tokens: - // 3) Redeem the VAA on the dest chain - console.log('Completing Transfer'); - const destTxids = await xfer.completeTransfer(route.destination.signer); - console.log(`Completed Transfer: `, destTxids); -``` + ```solidity + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + require(receivedTokens.length == 1, "Expected 1 token transfer"); -??? code "View the complete script" - ```ts hl_lines="122" - import { - Chain, - Network, - TokenId, - TokenTransfer, - Wormhole, - amount, - isTokenId, - wormhole, -} from '@wormhole-foundation/sdk'; + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { SignerStuff, getSigner, waitLog } from './helpers/index.js'; + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } + ``` -(async function () { - // Init Wormhole object, passing config for which network - // to use (e.g. Mainnet/Testnet) and what Platforms to support - const wh = await wormhole('Testnet', [evm, solana]); + This `receivePayloadAndTokens` function processes the tokens and payload sent from another chain, decodes the recipient address, and transfers the tokens to them using the Wormhole protocol. This function also validates the emitter (`sourceAddress`) to ensure the message comes from a trusted sender. - // Grab chain Contexts -- these hold a reference to a cached rpc client - const sendChain = wh.getChain('Avalanche'); - const rcvChain = wh.getChain('Solana'); + This function ensures that: - // Shortcut to allow transferring native gas token - const token = Wormhole.tokenId(sendChain.chain, 'native'); + - It only processes one token transfer at a time + - The `sourceAddress` is checked against a list of registered senders using the `isRegisteredSender` modifier, which verifies if the emitter is allowed to send tokens to this contract + - The recipient address is decoded from the payload, and the received tokens are transferred to them using the ERC-20 interface - // A TokenId is just a `{chain, address}` pair and an alias for ChainAddress - // The `address` field must be a parsed address. - // You can get a TokenId (or ChainAddress) prepared for you - // by calling the static `chainAddress` method on the Wormhole class. - // e.g. - // wAvax on Solana - // const token = Wormhole.tokenId("Solana", "3Ftc5hTz9sG4huk79onufGiebJNDMZNL8HYgdMJ9E7JR"); - // wSol on Avax - // const token = Wormhole.tokenId("Avalanche", "0xb10563644a6AB8948ee6d7f5b0a1fb15AaEa1E03"); +After we call `sendTokenWithPayloadToEvm` on the source chain, the message goes through the standard Wormhole message lifecycle. Once a [VAA (Verifiable Action Approval)](/docs/protocol/infrastructure/vaas/){target=\_blank} is available, the delivery provider will call `receivePayloadAndTokens` on the target chain and target address specified, with the appropriate inputs. - // Normalized given token decimals later but can just pass bigints as base units - // Note: The Token bridge will dedust past 8 decimals - // This means any amount specified past that point will be returned - // To the caller - const amt = '0.05'; +??? tip "Understanding the `TokenReceived` Struct" - // With automatic set to true, perform an automatic transfer. This will invoke a relayer - // Contract intermediary that knows to pick up the transfers - // With automatic set to false, perform a manual transfer from source to destination - // Of the token - // On the destination side, a wrapped version of the token will be minted - // To the address specified in the transfer VAA - const automatic = false; + Let’s delve into the fields provided to us in the `TokenReceived` struct: - // The Wormhole relayer has the ability to deliver some native gas funds to the destination account - // The amount specified for native gas will be swapped for the native gas token according - // To the swap rate provided by the contract, denominated in native gas tokens - const nativeGas = automatic ? '0.01' : undefined; + ```solidity + struct TokenReceived { + bytes32 tokenHomeAddress; + uint16 tokenHomeChain; + address tokenAddress; + uint256 amount; + uint256 amountNormalized; +} + ``` - // Get signer from local key but anything that implements - // Signer interface (e.g. wrapper around web wallet) should work - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); + - **`tokenHomeAddress`** - the original address of the token on its native chain. This is the same as the token field in the call to `sendTokenWithPayloadToEvm` unless the original token sent is a Wormhole-wrapped token. In that case, this will be the address of the original version of the token (on its native chain) in Wormhole address format (left-padded with 12 zeros) - // Used to normalize the amount to account for the tokens decimals - const decimals = isTokenId(token) - ? Number(await wh.getDecimals(token.chain, token.address)) - : sendChain.config.nativeTokenDecimals; + - **`tokenHomeChain`** - the Wormhole chain ID corresponding to the home address above. This will typically be the source chain unless the original token sent is a Wormhole-wrapped asset, which will be the chain of the unwrapped version of the token - // Set this to true if you want to perform a round trip transfer - const roundTrip: boolean = false; + - **`tokenAddress`** - the address of the IERC-20 token on the target chain that has been transferred to this contract. If `tokenHomeChain` equals the target chain, this will be the same as `tokenHomeAddress`; otherwise, it will be the Wormhole-wrapped version of the token sent - // Set this to the transfer txid of the initiating transaction to recover a token transfer - // And attempt to fetch details about its progress. - let recoverTxid = undefined; + - **`amount`** - the token amount sent to you with the same units as the original token. Since `TokenBridge` only sends with eight decimals of precision, if your token has 18 decimals, this will be the "amount" you sent, rounded down to the nearest multiple of 10^10 - // Finally create and perform the transfer given the parameters set above - const xfer = !recoverTxid - ? // Perform the token transfer - await tokenTransfer( - wh, - { - token, - amount: amount.units(amount.parse(amt, decimals)), - source, - destination, - delivery: { - automatic, - nativeGas: nativeGas - ? amount.units(amount.parse(nativeGas, decimals)) - : undefined, - }, - }, - roundTrip - ) - : // Recover the transfer from the originating txid - await TokenTransfer.from(wh, { - chain: source.chain.chain, - txid: recoverTxid, - }); + - **`amountNormalized`** - the amount of token divided by (1 if decimals ≤ 8, else 10^(decimals - 8)) - const receipt = await waitLog(wh, xfer); +You can find the complete code for the `CrossChainReceiver.sol` contract below: - // Log out the results - console.log(receipt); -})(); +??? code "CrossChainReceiver.sol" -async function tokenTransfer( - wh: Wormhole, - route: { - token: TokenId; - amount: bigint; - source: SignerStuff; - destination: SignerStuff; - delivery?: { - automatic: boolean; - nativeGas?: bigint; - }; - payload?: Uint8Array; - }, - roundTrip?: boolean -): Promise> { - // Create a TokenTransfer object to track the state of the transfer over time - const xfer = await wh.tokenTransfer( - route.token, - route.amount, - route.source.address, - route.destination.address, - route.delivery?.automatic ?? false, - route.payload, - route.delivery?.nativeGas - ); - - const quote = await TokenTransfer.quoteTransfer( - wh, - route.source.chain, - route.destination.chain, - xfer.transfer - ); - console.log(quote); - - if (xfer.transfer.automatic && quote.destinationToken.amount < 0) - throw 'The amount requested is too low to cover the fee and any native gas requested.'; + ```solidity + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; - // 1) Submit the transactions to the source chain, passing a signer to sign any txns - console.log('Starting transfer'); - const srcTxids = await xfer.initiateTransfer(route.source.signer); - console.log(`Started transfer: `, srcTxids); +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - // If automatic, we're done - if (route.delivery?.automatic) return xfer; +contract CrossChainReceiver is TokenReceiver { + // The Wormhole relayer and registeredSenders are inherited from the Base.sol contract - // 2) Wait for the VAA to be signed and ready (not required for auto transfer) - console.log('Getting Attestation'); - const attestIds = await xfer.fetchAttestation(60_000); - console.log(`Got Attestation: `, attestIds); + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - // 3) Redeem the VAA on the dest chain - console.log('Completing Transfer'); - const destTxids = await xfer.completeTransfer(route.destination.signer); - console.log(`Completed Transfer: `, destTxids); + // Function to receive the cross-chain payload and tokens with emitter validation + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + require(receivedTokens.length == 1, "Expected 1 token transfer"); - // If no need to send back, dip - if (!roundTrip) return xfer; + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); - const { destinationToken: token } = quote; - return await tokenTransfer(wh, { - ...route, - token: token.token, - amount: token.amount, - source: route.destination, - destination: route.source, - }); + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } } - ``` -Internally, this uses the [TokenBridge](#token-bridge) protocol client to transfer tokens. Like other Protocols, the `TokenBridge` protocol provides a consistent set of methods across all chains to generate a set of transactions for that specific chain. +## Deploy the Contracts -### Native USDC Transfers +Now that you've written the `CrossChainSender` and `CrossChainReceiver` contracts, it's time to deploy them to your chosen networks. -You can also transfer native USDC using [Circle's CCTP](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. Please note that if the transfer is set to `Automatic` mode, a fee for performing the relay will be included in the quote. This fee is deducted from the total amount requested to be sent. For example, if the user wishes to receive `1.0` on the destination, the amount sent should be adjusted to `1.0` plus the relay fee. The same principle applies to native gas drop offs. +1. **Set up deployment configuration** - before deploying, you must configure the networks and the deployment environment. This information is stored in a configuration file -In the following example, the `wh.circleTransfer` function is called with several parameters to set up the transfer. It takes the amount to be transferred (in the token's base units), the sender's chain and address, and the receiver's chain and address. The function also allows specifying whether the transfer should be automatic, meaning it will be completed without further user intervention. + 1. Create a directory named deploy-config in the root of your project: -An optional payload can be included with the transfer, though it's set to undefined in this case. Finally, if the transfer is automatic, you can request that native gas (the blockchain's native currency used for transaction fees) be sent to the receiver along with the transferred tokens. + ```bash + mkdir deploy-config + ``` -When waiting for the `VAA`, a timeout of `60,000` milliseconds is used. The amount of time required for the VAA to become available will [vary by network](https://developers.circle.com/stablecoins/docs/required-block-confirmations#mainnet){target=\_blank}. + 2. Create a `config.json` file in the `deploy-config` directory: -```ts -// Amount as bigint (base units) - req.amount, - // Sender chain/address - src.address, - // Receiver chain/address - dst.address, - // Automatic delivery boolean - req.automatic, - // Payload to be sent with the transfer - undefined, - // If automatic, native gas can be requested to be sent to the receiver - req.nativeGas - ); + ```bash + touch deploy-config/config.json + ``` - // Note, if the transfer is requested to be Automatic, a fee for performing the relay - // will be present in the quote. The fee comes out of the amount requested to be sent. - // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. - // The same applies for native gas dropoff - const quote = await CircleTransfer.quoteTransfer( - src.chain, - dst.chain, - xfer.transfer - ); - console.log('Quote', quote); + 3. Open the `config.json` file and add the following configuration: - console.log('Starting Transfer'); - const srcTxids = await xfer.initiateTransfer(src.signer); - console.log(`Started Transfer: `, srcTxids); + ```json + { + "chains": [ + { + "description": "Avalanche testnet fuji", + "chainId": 6, + "rpc": "https://api.avax-test.network/ext/bc/C/rpc", + "tokenBridge": "0x61E44E506Ca5659E6c0bba9b678586fA2d729756", + "wormholeRelayer": "0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB", + "wormhole": "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C" + }, + { + "description": "Celo Testnet", + "chainId": 14, + "rpc": "https://alfajores-forno.celo-testnet.org", + "tokenBridge": "0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153", + "wormholeRelayer": "0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84", + "wormhole": "0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56" + } + ] +} + ``` - if (req.automatic) { - const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); - console.log(`Finished relay: `, relayStatus); - return; - } + This file specifies the details for each chain where you plan to deploy your contracts, including the RPC URL, the `TokenBridge` address, the Wormhole relayer, and the Wormhole Core Contract. - console.log('Waiting for Attestation'); - const attestIds = await xfer.fetchAttestation(60_000); - console.log(`Got Attestation: `, attestIds); + For a complete list of Wormhole contract addresses on various blockchains, refer to the [Wormhole Contract Addresses](/docs/products/reference/contract-addresses/){target=_blank}. - console.log('Completing Transfer'); - const dstTxids = await xfer.completeTransfer(dst.signer); - console.log(`Completed Transfer: `, dstTxids); -} -``` + !!! note + You can add your desired chains to this file by specifying the required fields for each chain. In this example, we use the Avalanche Fuji and Celo Alfajores Testnets. -??? code "View the complete script" - ```ts - import { - Chain, - CircleTransfer, - Network, - Signer, - TransactionId, - TransferState, - Wormhole, - amount, - wormhole, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { SignerStuff, getSigner, waitForRelay } from './helpers/index.js'; + 4. Create a `contracts.json` file in the `deploy-config` directory: -/* -Notes: -Only a subset of chains are supported by Circle for CCTP, see core/base/src/constants/circle.ts for currently supported chains + ```bash + echo '{}' > deploy-config/contracts.json + ``` -AutoRelayer takes a 0.1 USDC fee when transferring to any chain beside Goerli, which is 1 USDC -*/ -// + This file can be left blank initially. It will be automatically updated with the deployed contract addresses after a successful deployment -(async function () { - // Init the Wormhole object, passing in the config for which network - // to use (e.g. Mainnet/Testnet) and what Platforms to support - const wh = await wormhole('Testnet', [evm, solana]); +2. **Set up your Node.js environment** - you'll need to set up your Node.js environment to run the deployment script - // Grab chain Contexts - const sendChain = wh.getChain('Avalanche'); - const rcvChain = wh.getChain('Solana'); + 1. Initialize a Node.js project: - // Get signer from local key but anything that implements - // Signer interface (e.g. wrapper around web wallet) should work - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); + ```bash + npm init -y + ``` - // 6 decimals for USDC (except for BSC, so check decimals before using this) - const amt = amount.units(amount.parse('0.2', 6)); + 2. Create a `.gitignore` file to ensure your private key isn't accidentally exposed or committed to version control: - // Choose whether or not to have the attestation delivered for you - const automatic = false; + ```bash + echo ".env" >> .gitignore + ``` + + 3. Install the necessary dependencies: - // If the transfer is requested to be automatic, you can also request that - // during redemption, the receiver gets some amount of native gas transferred to them - // so that they may pay for subsequent transactions - // The amount specified here is denominated in the token being transferred (USDC here) - const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + ```bash + npm install ethers dotenv readline-sync @types/readline-sync + ``` - await cctpTransfer(wh, source, destination, { - amount: amt, - automatic, - nativeGas, - }); + These dependencies are required for the deployment script to work properly. -})(); +3. **Compile your smart contracts** - compile your smart contracts using Foundry. This ensures that your contracts are up-to-date and ready for deployment -async function cctpTransfer( - wh: Wormhole, - src: SignerStuff, - dst: SignerStuff, - req: { - amount: bigint; - automatic: boolean; - nativeGas?: bigint; - } -) { + - Run the following command to compile your contracts: - const xfer = await wh.circleTransfer( - // Amount as bigint (base units) - req.amount, - // Sender chain/address - src.address, - // Receiver chain/address - dst.address, - // Automatic delivery boolean - req.automatic, - // Payload to be sent with the transfer - undefined, - // If automatic, native gas can be requested to be sent to the receiver - req.nativeGas - ); - - // Note, if the transfer is requested to be Automatic, a fee for performing the relay - // will be present in the quote. The fee comes out of the amount requested to be sent. - // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. - // The same applies for native gas dropoff - const quote = await CircleTransfer.quoteTransfer( - src.chain, - dst.chain, - xfer.transfer - ); - console.log('Quote', quote); + ```bash + forge build + ``` - console.log('Starting Transfer'); - const srcTxids = await xfer.initiateTransfer(src.signer); - console.log(`Started Transfer: `, srcTxids); + This will generate the necessary ABI and bytecode files in a directory named `/out`. - if (req.automatic) { - const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); - console.log(`Finished relay: `, relayStatus); - return; - } + The expected output should be similar to this: - console.log('Waiting for Attestation'); - const attestIds = await xfer.fetchAttestation(60_000); - console.log(`Got Attestation: `, attestIds); +
+forge build + > [⠒] Compiling... + > [⠰] Compiling 30 files with 0.8.23 + [⠔] Solc 0.8.23 finished in 2.29s +Compiler run successful! + +
- console.log('Completing Transfer'); - const dstTxids = await xfer.completeTransfer(dst.signer); - console.log(`Completed Transfer: `, dstTxids); -} +4. **Write the deployment script** - you’ll need a script to automate the deployment of your contracts. Let’s create the deployment script -export async function completeTransfer( - wh: Wormhole, - txid: TransactionId, - signer: Signer -): Promise { + 1. Create a new file named `deploy.ts` in the `/script` directory: - const xfer = await CircleTransfer.from(wh, txid); + ```bash + touch script/deploy.ts + ``` - const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); - console.log('Got attestation: ', attestIds); + 2. Open the file and load imports and configuration: - const dstTxIds = await xfer.completeTransfer(signer); - console.log('Completed transfer: ', dstTxIds); -} -
- ``` + ```typescript + import * as fs from 'fs'; +import * as path from 'path'; +import * as dotenv from 'dotenv'; +import readlineSync from 'readline-sync'; -### Recovering Transfers +dotenv.config(); + ``` -It may be necessary to recover an abandoned transfer before it is completed. To do this, instantiate the `Transfer` class with the `from` static method and pass one of several types of identifiers. A `TransactionId` or `WormholeMessageId` may be used to recover the transfer. + Import the required libraries and modules to interact with Ethereum, handle file paths, load environment variables, and enable user interaction via the terminal. -```ts -const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); - console.log('Got attestation: ', attestIds); + 3. Define interfaces to use for chain configuration and contract deployment: - const dstTxIds = await xfer.completeTransfer(signer); - console.log('Completed transfer: ', dstTxIds); -``` + ```typescript + description: string; + chainId: number; + rpc: string; + tokenBridge: string; + wormholeRelayer: string; + wormhole: string; +} -??? code "View the complete script" - ```ts hl_lines="130" - import { - Chain, - CircleTransfer, - Network, - Signer, - TransactionId, - TransferState, - Wormhole, - amount, - wormhole, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { SignerStuff, getSigner, waitForRelay } from './helpers/index.js'; +interface DeployedContracts { + [chainId: number]: { + networkName: string; + CrossChainSender?: string; + CrossChainReceiver?: string; + deployedAt: string; + }; +} + ``` -/* -Notes: -Only a subset of chains are supported by Circle for CCTP, see core/base/src/constants/circle.ts for currently supported chains + These interfaces define the structure of the chain configuration and the contract deployment details. -AutoRelayer takes a 0.1 USDC fee when transferring to any chain beside Goerli, which is 1 USDC -*/ -// + 4. Load and select the chains for deployment: -(async function () { - // Init the Wormhole object, passing in the config for which network - // to use (e.g. Mainnet/Testnet) and what Platforms to support - const wh = await wormhole('Testnet', [evm, solana]); + ```typescript + const configPath = path.resolve(__dirname, '../deploy-config/config.json'); + return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; +} - // Grab chain Contexts - const sendChain = wh.getChain('Avalanche'); - const rcvChain = wh.getChain('Solana'); +function selectChain( + chains: ChainConfig[], + role: 'source' | 'target' +): ChainConfig { + console.log(`\nSelect the ${role.toUpperCase()} chain:`); + chains.forEach((chain, index) => { + console.log(`${index + 1}: ${chain.description}`); + }); - // Get signer from local key but anything that implements - // Signer interface (e.g. wrapper around web wallet) should work - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); + const chainIndex = + readlineSync.questionInt( + `\nEnter the number for the ${role.toUpperCase()} chain: ` + ) - 1; + return chains[chainIndex]; +} + ``` - // 6 decimals for USDC (except for BSC, so check decimals before using this) - const amt = amount.units(amount.parse('0.2', 6)); + The `loadConfig` function reads the chain configuration from the `config.json` file, and the `selectChain` function allows the user to choose the source and target chains for deployment interactively. The user is prompted in the terminal to select which chains to use, making the process interactive and user-friendly. - // Choose whether or not to have the attestation delivered for you - const automatic = false; + 5. Define the main function for deployment and load the chain configuration: - // If the transfer is requested to be automatic, you can also request that - // during redemption, the receiver gets some amount of native gas transferred to them - // so that they may pay for subsequent transactions - // The amount specified here is denominated in the token being transferred (USDC here) - const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; + ```typescript + const chains = loadConfig(); - await cctpTransfer(wh, source, destination, { - amount: amt, - automatic, - nativeGas, - }); + const sourceChain = selectChain(chains, 'source'); + const targetChain = selectChain(chains, 'target'); + ``` -})(); + - The `main` function is the entry point for the deployment script + - We then call the `loadConfig` function we previously defined to load the chain configuration from the `config.json` file -async function cctpTransfer( - wh: Wormhole, - src: SignerStuff, - dst: SignerStuff, - req: { - amount: bigint; - automatic: boolean; - nativeGas?: bigint; - } -) { + 6. Set up provider and wallet: + + ```typescript + const targetProvider = new ethers.JsonRpcProvider(targetChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); + ``` + + The scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction on the source chain. - const xfer = await wh.circleTransfer( - // Amount as bigint (base units) - req.amount, - // Sender chain/address - src.address, - // Receiver chain/address - dst.address, - // Automatic delivery boolean - req.automatic, - // Payload to be sent with the transfer - undefined, - // If automatic, native gas can be requested to be sent to the receiver - req.nativeGas - ); + 7. Read the compiled contracts: - // Note, if the transfer is requested to be Automatic, a fee for performing the relay - // will be present in the quote. The fee comes out of the amount requested to be sent. - // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. - // The same applies for native gas dropoff - const quote = await CircleTransfer.quoteTransfer( - src.chain, - dst.chain, - xfer.transfer + ```typescript + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' + ), + 'utf8' + ) ); - console.log('Quote', quote); - - console.log('Starting Transfer'); - const srcTxids = await xfer.initiateTransfer(src.signer); - console.log(`Started Transfer: `, srcTxids); + ``` - if (req.automatic) { - const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); - console.log(`Finished relay: `, relayStatus); - return; - } + - This code reads the `CrossChainSender.json` file, the compiled output of the `CrossChainSender.sol` contract + - The file is in the `../out/` directory, which contains the ABI (Application Binary Interface) and bytecode generated during contract compilation + - It uses the `fs.readFileSync` function to read the file and `JSON.parse` to convert the file contents (in JSON format) into a JavaScript object - console.log('Waiting for Attestation'); - const attestIds = await xfer.fetchAttestation(60_000); - console.log(`Got Attestation: `, attestIds); + 8. Extract the contract ABI and bytecode: - console.log('Completing Transfer'); - const dstTxids = await xfer.completeTransfer(dst.signer); - console.log(`Completed Transfer: `, dstTxids); -} + ```typescript + const bytecode = senderJson.bytecode; + ``` -export async function completeTransfer( - wh: Wormhole, - txid: TransactionId, - signer: Signer -): Promise { + - **ABI (Application Binary Interface)** - defines the structure of the contract’s functions, events, and data types, allowing the front end to interact with the contract on the blockchain + - **Bytecode** - this is the compiled machine code that will be deployed to the blockchain to create the contract - const xfer = await CircleTransfer.from(wh, txid); + 9. Create the Contract Factory: - const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); - console.log('Got attestation: ', attestIds); + ```typescript + abi, + bytecode, + wallet + ); + ``` - const dstTxIds = await xfer.completeTransfer(signer); - console.log('Completed transfer: ', dstTxIds); -} - - ``` + - **`ethers.ContractFactory`** - creates a new contract factory using the ABI, bytecode, and a wallet (representing the signer). The contract factory is responsible for deploying instances of the contract to the blockchain + - This is a crucial step for deploying the contract since the factory will create and deploy the `CrossChainSender` contract -## Routes + 10. Deploy the `CrossChainSender` and `CrossChainReceiver` contracts: -While a specific `WormholeTransfer`, such as `TokenTransfer` or `CCTPTransfer`, may be used, the developer must know exactly which transfer type to use for a given request. + === "`CrossChainSender`" + ```typescript + const senderContract = await CrossChainSenderFactory.deploy( + sourceChain.wormholeRelayer, + sourceChain.tokenBridge, + sourceChain.wormhole + ); + await senderContract.waitForDeployment(); + ``` -To provide a more flexible and generic interface, the `Wormhole` class provides a method to produce a `RouteResolver` that can be configured with a set of possible routes to be supported. + === "`CrossChainReceiver`" + ```typescript + process.env.PRIVATE_KEY!, + targetProvider + ); + const receiverJson = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainReceiver.sol/CrossChainReceiver.json' + ), + 'utf8' + ) + ); + const CrossChainReceiverFactory = new ethers.ContractFactory( + receiverJson.abi, + receiverJson.bytecode, + targetWallet + ); -The following section demonstrates setting up and validating a token transfer using Wormhole's routing system. + const receiverContract = await CrossChainReceiverFactory.deploy( + targetChain.wormholeRelayer, + targetChain.tokenBridge, + targetChain.wormhole + ); + await receiverContract.waitForDeployment(); + ``` -```ts -const resolver = wh.resolver([ - routes.TokenBridgeRoute, // manual token bridge - routes.AutomaticTokenBridgeRoute, // automatic token bridge - routes.CCTPRoute, // manual CCTP - routes.AutomaticCCTPRoute, // automatic CCTP - routes.AutomaticPorticoRoute, // Native eth transfers - ]); -``` + Both functions deploy the respective contracts to the selected chains. -Once created, the resolver can be used to provide a list of input and possible output tokens. + For the `CrossChainReceiver` contract: -```ts -const srcTokens = await resolver.supportedSourceTokens(sendChain); - console.log( - 'Allowed source tokens: ', - srcTokens.map((t) => canonicalAddress(t)) - ); + - It defines the wallet related to the target chain + - The logic reads the compiled ABI and bytecode from the JSON file generated during compilation + - It creates a new contract factory using the ABI, bytecode, and wallet + - It deploys the contract to the selected chain passing in the Wormhole Relayer, `TokenBridge`, and Wormhole addresses - const sendToken = Wormhole.tokenId(sendChain.chain, 'native'); + 11. Save the deployed contract addresses: - // Given the send token, what can we possibly get on the destination chain? - const destTokens = await resolver.supportedDestinationTokens( - sendToken, - sendChain, - destChain - ); - console.log( - 'For the given source token and routes configured, the following tokens may be receivable: ', - destTokens.map((t) => canonicalAddress(t)) - ); - // Grab the first one for the example - const destinationToken = destTokens[0]!; -``` + === "`senderAddress`" + ```typescript + console.log( + `CrossChainSender on ${sourceChain.description}: ${senderAddress}` + ); + ``` -Once the tokens are selected, a `RouteTransferRequest` may be created to provide a list of routes that can fulfill the request. Creating a transfer request fetches the token details since all routes will need to know about the tokens. + === "`receiverAddress`" + ```typescript + console.log( + `CrossChainReceiver on ${targetChain.description}: ${receiverAddress}` + ); + ``` -```ts -// Since all routes will need to know about the tokens - const tr = await routes.RouteTransferRequest.create(wh, { - source: sendToken, - destination: destinationToken, - }); + You may display the deployed contract addresses in the terminal or save them to a JSON file for future reference. - // Resolve the transfer request to a set of routes that can perform it - const foundRoutes = await resolver.findRoutes(tr); - console.log( - 'For the transfer parameters, we found these routes: ', - foundRoutes - ); -``` + 12. Register the `CrossChainSender` address on the target chain: + + ```typescript + receiverAddress, + receiverJson.abi, + targetWallet + ); + + const tx = await CrossChainReceiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) + ); -Choosing the best route is currently left to the developer, but strategies might include sorting by output amount or expected time to complete the transfer (no estimate is currently provided). + await tx.wait(); + ``` -After choosing the best route, extra parameters like `amount`, `nativeGasDropoff`, and `slippage` can be passed, depending on the specific route selected. A quote can be retrieved with the validated request. + After you deploy the `CrossChainReceiver` contract on the target network, the sender contract address from the source chain needs to be registered. This ensures that only messages from the registered `CrossChainSender` contract are processed. -After successful validation, the code requests a transfer quote. This quote likely includes important details such as fees, estimated time, and the final amount to be received. If the quote is generated successfully, it's displayed for the user to review and decide whether to proceed with the transfer. This process ensures that all transfer details are properly set up and verified before any actual transfer occurs. + This additional step is essential to enforce emitter validation, preventing unauthorized senders from delivering messages to the `CrossChainReceiver` contract. -```ts -'This route offers the following default options', - bestRoute.getDefaultOptions() - ); + 13. Save the deployment details: - // Specify the amount as a decimal string - const amt = '0.001'; - // Create the transfer params for this request - const transferParams = { amount: amt, options: { nativeGas: 0 } }; + ???- example "Save Deployment Details Example" + ```typescript + __dirname, + '../deploy-config/contracts.json' + ); + let deployedContracts: DeployedContracts = {}; - // Validate the transfer params passed, this returns a new type of ValidatedTransferParams - // which (believe it or not) is a validated version of the input params - // This new var must be passed to the next step, quote - const validated = await bestRoute.validate(tr, transferParams); - if (!validated.valid) throw validated.error; - console.log('Validated parameters: ', validated.params); + if (fs.existsSync(deployedContractsPath)) { + deployedContracts = JSON.parse( + fs.readFileSync(deployedContractsPath, 'utf8') + ); + } - // Get a quote for the transfer, this too returns a new type that must - // be passed to the next step, execute (if you like the quote) - const quote = await bestRoute.quote(tr, validated.params); - if (!quote.success) throw quote.error; - console.log('Best route quote: ', quote); -``` + // Update the contracts.json file: + // If a contract already exists on a chain, update its address; otherwise, add a new entry. + if (!deployedContracts[sourceChain.chainId]) { + deployedContracts[sourceChain.chainId] = { + networkName: sourceChain.description, + deployedAt: new Date().toISOString(), + }; + } + deployedContracts[sourceChain.chainId].CrossChainSender = + senderAddress.toString(); + deployedContracts[sourceChain.chainId].deployedAt = + new Date().toISOString(); -Finally, assuming the quote looks good, the route can initiate the request with the quote and the `signer`. + if (!deployedContracts[targetChain.chainId]) { + deployedContracts[targetChain.chainId] = { + networkName: targetChain.description, + deployedAt: new Date().toISOString(), + }; + } + deployedContracts[targetChain.chainId].CrossChainReceiver = + receiverAddress.toString(); + deployedContracts[targetChain.chainId].deployedAt = + new Date().toISOString(); -```ts -tr, - sender.signer, - quote, - receiver.address + // Save the updated contracts.json file + fs.writeFileSync( + deployedContractsPath, + JSON.stringify(deployedContracts, null, 2) ); - console.log('Initiated transfer with receipt: ', receipt); -``` + ``` + + Add your desired logic to save the deployed contract addresses in a JSON file (or another format). This will be important later when transferring tokens, as you'll need these addresses to interact with the deployed contracts. -??? code "View the complete script" + 14. Handle errors and finalize the script: - ```ts - import { - Wormhole, - canonicalAddress, - routes, - wormhole, -} from '@wormhole-foundation/sdk'; + ```typescript + if (error.code === 'INSUFFICIENT_FUNDS') { + console.error( + 'Error: Insufficient funds for deployment. Please make sure your wallet has enough funds to cover the gas fees.' + ); + } else { + console.error('An unexpected error occurred:', error.message); + } + process.exit(1); + } +} -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { getSigner } from './helpers/index.js'; +main().catch((error) => { + console.error(error); + process.exit(1); +}); + ``` -(async function () { - // Setup - const wh = await wormhole('Testnet', [evm, solana]); + The try-catch block wraps the deployment logic to catch any errors that may occur. - // Get chain contexts - const sendChain = wh.getChain('Avalanche'); - const destChain = wh.getChain('Solana'); + - If the error is due to insufficient funds, it logs a clear message about needing more gas fees + - For any other errors, it logs the specific error message to help with debugging - // Get signers from local config - const sender = await getSigner(sendChain); - const receiver = await getSigner(destChain); + The `process.exit(1)` ensures that the script exits with a failure status code if any error occurs. - // Create new resolver, passing the set of routes to consider - const resolver = wh.resolver([ - routes.TokenBridgeRoute, // manual token bridge - routes.AutomaticTokenBridgeRoute, // automatic token bridge - routes.CCTPRoute, // manual CCTP - routes.AutomaticCCTPRoute, // automatic CCTP - routes.AutomaticPorticoRoute, // Native eth transfers - ]); + You can find the full code for the `deploy.ts` file below: - // What tokens are available on the source chain? - const srcTokens = await resolver.supportedSourceTokens(sendChain); - console.log( - 'Allowed source tokens: ', - srcTokens.map((t) => canonicalAddress(t)) - ); + ??? code "deploy.ts" - const sendToken = Wormhole.tokenId(sendChain.chain, 'native'); + ```solidity + import { BytesLike, ethers } from 'ethers'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as dotenv from 'dotenv'; +import readlineSync from 'readline-sync'; - // Given the send token, what can we possibly get on the destination chain? - const destTokens = await resolver.supportedDestinationTokens( - sendToken, - sendChain, - destChain - ); - console.log( - 'For the given source token and routes configured, the following tokens may be receivable: ', - destTokens.map((t) => canonicalAddress(t)) - ); - // Grab the first one for the example - const destinationToken = destTokens[0]!; +dotenv.config(); - // Creating a transfer request fetches token details - // Since all routes will need to know about the tokens - const tr = await routes.RouteTransferRequest.create(wh, { - source: sendToken, - destination: destinationToken, - }); +interface ChainConfig { + description: string; + chainId: number; + rpc: string; + tokenBridge: string; + wormholeRelayer: string; + wormhole: string; +} - // Resolve the transfer request to a set of routes that can perform it - const foundRoutes = await resolver.findRoutes(tr); - console.log( - 'For the transfer parameters, we found these routes: ', - foundRoutes - ); +interface DeployedContracts { + [chainId: number]: { + networkName: string; + CrossChainSender?: string; + CrossChainReceiver?: string; + deployedAt: string; + }; +} - const bestRoute = foundRoutes[0]!; - console.log('Selected: ', bestRoute); +function loadConfig(): ChainConfig[] { + const configPath = path.resolve(__dirname, '../deploy-config/config.json'); + return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; +} - console.log( - 'This route offers the following default options', - bestRoute.getDefaultOptions() - ); +function selectChain( + chains: ChainConfig[], + role: 'source' | 'target' +): ChainConfig { + console.log(`\nSelect the ${role.toUpperCase()} chain:`); + chains.forEach((chain, index) => { + console.log(`${index + 1}: ${chain.description}`); + }); - // Specify the amount as a decimal string - const amt = '0.001'; - // Create the transfer params for this request - const transferParams = { amount: amt, options: { nativeGas: 0 } }; + const chainIndex = + readlineSync.questionInt( + `\nEnter the number for the ${role.toUpperCase()} chain: ` + ) - 1; + return chains[chainIndex]; +} - // Validate the transfer params passed, this returns a new type of ValidatedTransferParams - // which (believe it or not) is a validated version of the input params - // This new var must be passed to the next step, quote - const validated = await bestRoute.validate(tr, transferParams); - if (!validated.valid) throw validated.error; - console.log('Validated parameters: ', validated.params); +async function main() { + const chains = loadConfig(); - // Get a quote for the transfer, this too returns a new type that must - // be passed to the next step, execute (if you like the quote) - const quote = await bestRoute.quote(tr, validated.params); - if (!quote.success) throw quote.error; - console.log('Best route quote: ', quote); + const sourceChain = selectChain(chains, 'source'); + const targetChain = selectChain(chains, 'target'); - // If you're sure you want to do this, set this to true - const imSure = false; - if (imSure) { - // Now the transfer may be initiated - // A receipt will be returned, guess what you gotta do with that? - const receipt = await bestRoute.initiate( - tr, - sender.signer, - quote, - receiver.address - ); - console.log('Initiated transfer with receipt: ', receipt); + const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); + const targetProvider = new ethers.JsonRpcProvider(targetChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); - // Kick off a wait log, if there is an opportunity to complete, this function will do it - // See the implementation for how this works - await routes.checkAndCompleteTransfer(bestRoute, receipt, receiver.signer); - } else { - console.log('Not initiating transfer (set `imSure` to true to do so)'); - } -})(); - ``` + const senderJson = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' + ), + 'utf8' + ) + ); -See the `router.ts` example in the [examples directory](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/examples){target=\_blank} for a full working example. + const abi = senderJson.abi; + const bytecode = senderJson.bytecode; -### Routes as Plugins + const CrossChainSenderFactory = new ethers.ContractFactory( + abi, + bytecode, + wallet + ); -Routes can be imported from any npm package that exports them and configured with the resolver. Custom routes must extend [`Route`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L21-L64){target=\_blank} and implement [`StaticRouteMethods`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L101){target=\_blank}. + try { + const senderContract = await CrossChainSenderFactory.deploy( + sourceChain.wormholeRelayer, + sourceChain.tokenBridge, + sourceChain.wormhole + ); + await senderContract.waitForDeployment(); -```ts -import { Network, routes } from '@wormhole-foundation/sdk-connect'; + // Safely access the deployed contract's address + const senderAddress = (senderContract as ethers.Contract).target; + console.log( + `CrossChainSender on ${sourceChain.description}: ${senderAddress}` + ); -export class CustomRoute - extends routes.Route - implements routes.StaticRouteMethods -{ - static meta = { - name: 'CustomRoute', - }; - // implementation... -} - -``` + const targetWallet = new ethers.Wallet( + process.env.PRIVATE_KEY!, + targetProvider + ); + const receiverJson = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainReceiver.sol/CrossChainReceiver.json' + ), + 'utf8' + ) + ); + const CrossChainReceiverFactory = new ethers.ContractFactory( + receiverJson.abi, + receiverJson.bytecode, + targetWallet + ); -A noteworthy example of a route exported from a separate npm package is Wormhole Native Token Transfers (NTT). See the [`NttAutomaticRoute`](https://github.com/wormhole-foundation/native-token-transfers/blob/66f8e414223a77f5c736541db0a7a85396cab71c/sdk/route/src/automatic.ts#L48){target=\_blank} route implementation. + const receiverContract = await CrossChainReceiverFactory.deploy( + targetChain.wormholeRelayer, + targetChain.tokenBridge, + targetChain.wormhole + ); + await receiverContract.waitForDeployment(); -## See Also + // Safely access the deployed contract's address + const receiverAddress = (receiverContract as ethers.Contract).target; + console.log( + `CrossChainReceiver on ${targetChain.description}: ${receiverAddress}` + ); -The TSdoc is available [on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank}. ---- END CONTENT --- + // Register the sender contract in the receiver contract + console.log( + `Registering CrossChainSender (${senderAddress}) as a valid sender in CrossChainReceiver (${receiverAddress})...` + ); -Doc-Content: https://wormhole.com/docs/build/transfers/cctp/ ---- BEGIN CONTENT --- ---- -title: Interacting with CCTP Contracts -description: Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. -categories: Transfer ---- + const CrossChainReceiverContract = new ethers.Contract( + receiverAddress, + receiverJson.abi, + targetWallet + ); -# Get Started with CCTP + const tx = await CrossChainReceiverContract.setRegisteredSender( + sourceChain.chainId, + ethers.zeroPadValue(senderAddress as BytesLike, 32) + ); -## Introduction + await tx.wait(); + console.log( + `CrossChainSender registered as a valid sender on ${targetChain.description}` + ); -Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/learn/transfers/cctp/){target=\_blank} by Circle is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. + // Load existing deployed contract addresses from contracts.json + const deployedContractsPath = path.resolve( + __dirname, + '../deploy-config/contracts.json' + ); + let deployedContracts: DeployedContracts = {}; -As decentralized finance (DeFi) protocols evolve, the need for flexible, secure cross-chain messaging has expanded, requiring solutions beyond simple asset transfers. Wormhole enhances CCTP's capabilities by allowing developers to compose more complex cross-chain interactions. With Wormhole's generic messaging, applications can execute smart contract logic alongside native USDC transfers, enabling richer, more versatile cross-chain experiences. + if (fs.existsSync(deployedContractsPath)) { + deployedContracts = JSON.parse( + fs.readFileSync(deployedContractsPath, 'utf8') + ); + } -This guide will walk you through getting started with Wormhole's CCTP contracts and show you how to integrate CCTP into your smart contracts, enabling the composition of advanced cross-chain functions with native USDC transfers. + // Update the contracts.json file: + // If a contract already exists on a chain, update its address; otherwise, add a new entry. + if (!deployedContracts[sourceChain.chainId]) { + deployedContracts[sourceChain.chainId] = { + networkName: sourceChain.description, + deployedAt: new Date().toISOString(), + }; + } + deployedContracts[sourceChain.chainId].CrossChainSender = + senderAddress.toString(); + deployedContracts[sourceChain.chainId].deployedAt = + new Date().toISOString(); -## Prerequisites + if (!deployedContracts[targetChain.chainId]) { + deployedContracts[targetChain.chainId] = { + networkName: targetChain.description, + deployedAt: new Date().toISOString(), + }; + } + deployedContracts[targetChain.chainId].CrossChainReceiver = + receiverAddress.toString(); + deployedContracts[targetChain.chainId].deployedAt = + new Date().toISOString(); -To interact with the Wormhole CCTP, you'll need the following: + // Save the updated contracts.json file + fs.writeFileSync( + deployedContractsPath, + JSON.stringify(deployedContracts, null, 2) + ); + } catch (error: any) { + if (error.code === 'INSUFFICIENT_FUNDS') { + console.error( + 'Error: Insufficient funds for deployment. Please make sure your wallet has enough funds to cover the gas fees.' + ); + } else { + console.error('An unexpected error occurred:', error.message); + } + process.exit(1); + } +} -- [The address of the CCTP contract](/docs/build/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +main().catch((error) => { + console.error(error); + process.exit(1); +}); + ``` -## Wormhole's CCTP Integration Contract +5. **Add your private key** - you'll need to provide your private key. It allows your deployment script to sign the transactions that deploy the smart contracts to the blockchain. Without it, the script won't be able to interact with the blockchain on your behalf -Wormhole's Circle Integration contract, `CircleIntegration.sol`, is the contract you'll interact with directly. It burns and mints Circle-supported tokens by using [Circle's CCTP contracts](#circles-cctp-contracts). + Create a `.env` file in the root of the project and add your private key: -The Circle Integration contract emits Wormhole messages with arbitrary payloads to allow additional composability when performing cross-chain transfers of Circle-supported assets. + ```bash + touch .env + ``` -This contract can be found in [Wormhole's `wormhole-circle-integration` repository](https://github.com/wormhole-foundation/wormhole-circle-integration/){target=\_blank} on GitHub. + Inside `.env`, add your private key in the following format: -!!! note - Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/build/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. + ```env + PRIVATE_KEY=INSERT_PRIVATE_KEY + ``` + +6. **Run the deployment script** -??? code "Circle Integration contract" - ```solidity - // SPDX-License-Identifier: Apache 2 -pragma solidity ^0.8.19; + 1. Open a terminal and run the following command: -import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {IWormhole} from "wormhole/interfaces/IWormhole.sol"; -import {BytesLib} from "wormhole/libraries/external/BytesLib.sol"; + ```bash + npx ts-node script/deploy.ts + ``` -import {ICircleBridge} from "../interfaces/circle/ICircleBridge.sol"; + This will execute the deployment script, deploying both contracts to the selected chains. -import {CircleIntegrationGovernance} from "./CircleIntegrationGovernance.sol"; -import {CircleIntegrationMessages} from "./CircleIntegrationMessages.sol"; + 2. Check the deployment output: -/** - * @notice This contract burns and mints Circle-supported tokens by using Circle's Cross-Chain Transfer Protocol. It also emits - * Wormhole messages with arbitrary payloads to allow for additional composability when performing cross-chain - * transfers of Circle-suppored assets. - */ -contract CircleIntegration is - CircleIntegrationMessages, - CircleIntegrationGovernance, - ReentrancyGuard -{ - using BytesLib for bytes; + - You will see the deployed contract addresses printed in the terminal if successful. The `contracts.json` file will be updated with these addresses + - If you encounter an error, the script will provide feedback, such as insufficient funds for gas - /** - * @notice Emitted when Circle-supported assets have been minted to the mintRecipient - * @param emitterChainId Wormhole chain ID of emitter contract on source chain - * @param emitterAddress Address (bytes32 zero-left-padded) of emitter on source chain - * @param sequence Sequence of Wormhole message used to mint tokens - */ - event Redeemed( - uint16 indexed emitterChainId, - bytes32 indexed emitterAddress, - uint64 indexed sequence - ); +If you followed the logic provided in the full code above, your terminal output should look something like this: - /** - * @notice `transferTokensWithPayload` calls the Circle Bridge contract to burn Circle-supported tokens. It emits - * a Wormhole message containing a user-specified payload with instructions for what to do with - * the Circle-supported assets once they have been minted on the target chain. - * @dev reverts if: - * - user passes insufficient value to pay Wormhole message fee - * - `token` is not supported by Circle Bridge - * - `amount` is zero - * - `targetChain` is not supported - * - `mintRecipient` is bytes32(0) - * @param transferParams Struct containing the following attributes: - * - `token` Address of the token to be burned - * - `amount` Amount of `token` to be burned - * - `targetChain` Wormhole chain ID of the target blockchain - * - `mintRecipient` The recipient wallet or contract address on the target chain - * @param batchId ID for Wormhole message batching - * @param payload Arbitrary payload to be delivered to the target chain via Wormhole - * @return messageSequence Wormhole sequence number for this contract - */ - function transferTokensWithPayload( - TransferParameters memory transferParams, - uint32 batchId, - bytes memory payload - ) public payable nonReentrant returns (uint64 messageSequence) { - // cache wormhole instance and fees to save on gas - IWormhole wormhole = wormhole(); - uint256 wormholeFee = wormhole.messageFee(); +
+npx ts-node deploy.ts + > cross-chain-token-transfer@1.0.0 deploy + > npx ts-node script/deploy.ts + Select the SOURCE chain: + 1: Avalanche testnet fuji + 2: Celo Testnet + + Enter the number for the SOURCE chain: 1 + + Select the TARGET chain: + 1: Avalanche testnet fuji + 2: Celo Testnet + + Enter the number for the TARGET chain: 2 + CrossChainSender Avalanche testnet fuji: 0x1Cac52a183D02F9002fdb37b13eC2fAB950d44E3 + CrossChainReceiver Celo Testnet: 0xD720BFF42a0960cfF1118454A907a44dB358f2b1 + + Registering CrossChainSender (0x1Cac52a183D02F9002fdb37b13eC2fAB950d44E3) as a valid sender in CrossChainReceiver (0xD720BFF42a0960cfF1118454A907a44dB358f2b1)... + + CrossChainSender registered as a valid sender on Celo Testnet + +
- // confirm that the caller has sent enough ether to pay for the wormhole message fee - require(msg.value == wormholeFee, "insufficient value"); - // Call the circle bridge and `depositForBurnWithCaller`. The `mintRecipient` - // should be the target contract (or wallet) composing on this contract. - (uint64 nonce, uint256 amountReceived) = _transferTokens( - transferParams.token, - transferParams.amount, - transferParams.targetChain, - transferParams.mintRecipient - ); +## Transfer Tokens Across Chains - // encode DepositWithPayload message - bytes memory encodedMessage = encodeDepositWithPayload( - DepositWithPayload({ - token: addressToBytes32(transferParams.token), - amount: amountReceived, - sourceDomain: localDomain(), - targetDomain: getDomainFromChainId(transferParams.targetChain), - nonce: nonce, - fromAddress: addressToBytes32(msg.sender), - mintRecipient: transferParams.mintRecipient, - payload: payload - }) - ); +### Quick Recap - // send the DepositWithPayload wormhole message - messageSequence = wormhole.publishMessage{value: wormholeFee}( - batchId, - encodedMessage, - wormholeFinality() - ); - } +Up to this point, you've set up a new Solidity project using Foundry, developed two key contracts (`CrossChainSender` and `CrossChainReceiver`), and created a deployment script to deploy these contracts to different blockchain networks. The deployment script also saves the new contract addresses for easy reference. With everything in place, it's time to transfer tokens using the deployed contracts. - function _transferTokens( - address token, - uint256 amount, - uint16 targetChain, - bytes32 mintRecipient - ) internal returns (uint64 nonce, uint256 amountReceived) { - // sanity check user input - require(amount > 0, "amount must be > 0"); - require(mintRecipient != bytes32(0), "invalid mint recipient"); - require(isAcceptedToken(token), "token not accepted"); - require( - getRegisteredEmitter(targetChain) != bytes32(0), - "target contract not registered" - ); +In this step, you'll write a script to transfer tokens across chains using the `CrossChainSender` and `CrossChainReceiver` contracts you deployed earlier. This script will interact with the contracts and facilitate the cross-chain token transfer. - // take custody of tokens - amountReceived = custodyTokens(token, amount); +### Transfer Script - // cache Circle Bridge instance - ICircleBridge circleBridge = circleBridge(); +1. **Set up the transfer script** - // approve the Circle Bridge to spend tokens - SafeERC20.safeApprove( - IERC20(token), - address(circleBridge), - amountReceived - ); + 1. Create a new file named `transfer.ts` in the `/script` directory: - // burn tokens on the bridge - nonce = circleBridge.depositForBurnWithCaller( - amountReceived, - getDomainFromChainId(targetChain), - mintRecipient, - token, - getRegisteredEmitter(targetChain) - ); - } + ```bash + touch script/transfer.ts + ``` - function custodyTokens( - address token, - uint256 amount - ) internal returns (uint256) { - // query own token balance before transfer - (, bytes memory queriedBalanceBefore) = token.staticcall( - abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)) - ); - uint256 balanceBefore = abi.decode(queriedBalanceBefore, (uint256)); + 2. Open the file. Start with the necessary imports, interfaces and configurations: - // deposit tokens - SafeERC20.safeTransferFrom( - IERC20(token), - msg.sender, - address(this), - amount - ); + ```typescript + import * as fs from 'fs'; +import * as path from 'path'; +import * as dotenv from 'dotenv'; +import readlineSync from 'readline-sync'; - // query own token balance after transfer - (, bytes memory queriedBalanceAfter) = token.staticcall( - abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)) - ); - uint256 balanceAfter = abi.decode(queriedBalanceAfter, (uint256)); +dotenv.config(); - return balanceAfter - balanceBefore; - } +interface ChainConfig { + description: string; + chainId: number; + rpc: string; + tokenBridge: string; + wormholeRelayer: string; + wormhole: string; +} - /** - * @notice `redeemTokensWithPayload` verifies the Wormhole message from the source chain and - * verifies that the passed Circle Bridge message is valid. It calls the Circle Bridge - * contract by passing the Circle message and attestation to mint tokens to the specified - * mint recipient. It also verifies that the caller is the specified mint recipient to ensure - * atomic execution of the additional instructions in the Wormhole message. - * @dev reverts if: - * - Wormhole message is not properly attested - * - Wormhole message was not emitted from a registered contrat - * - Wormhole message was already consumed by this contract - * - msg.sender is not the encoded mintRecipient - * - Circle Bridge message and Wormhole message are not associated - * - `receiveMessage` call to Circle Transmitter fails - * @param params Struct containing the following attributes: - * - `encodedWormholeMessage` Wormhole message emitted by a registered contract including - * information regarding the token burn on the source chain and an arbitrary message. - * - `circleBridgeMessage` Message emitted by Circle Bridge contract with information regarding - * the token burn on the source chain. - * - `circleAttestation` Serialized EC Signature attesting the cross-chain transfer - * @return depositInfo Struct containing the following attributes: - * - `token` Address (bytes32 left-zero-padded) of token to be minted - * - `amount` Amount of tokens to be minted - * - `sourceDomain` Circle domain for the source chain - * - `targetDomain` Circle domain for the target chain - * - `nonce` Circle sequence number for the transfer - * - `fromAddress` Source CircleIntegration contract caller's address - * - `mintRecipient` Recipient of minted tokens (must be caller of this contract) - * - `payload` Arbitrary Wormhole message payload - */ - function redeemTokensWithPayload( - RedeemParameters calldata params - ) public returns (DepositWithPayload memory depositInfo) { - // verify the wormhole message - IWormhole.VM memory verifiedMessage = verifyWormholeRedeemMessage( - params.encodedWormholeMessage - ); - - // Decode the message payload into the DepositWithPayload struct. Call the Circle TokenMinter - // contract to determine the address of the encoded token on this chain. - depositInfo = decodeDepositWithPayload(verifiedMessage.payload); - depositInfo.token = fetchLocalTokenAddress( - depositInfo.sourceDomain, - depositInfo.token - ); +interface DeployedContracts { + [chainId: number]: { + networkName: string; + CrossChainSender?: string; + CrossChainReceiver?: string; + deployedAt: string; + }; +} + ``` - // confirm that circle gave us a valid token address - require(depositInfo.token != bytes32(0), "invalid local token address"); + These imports include the essential libraries for interacting with Ethereum, handling file paths, loading environment variables, and managing user input. - // confirm that the caller is the `mintRecipient` to ensure atomic execution - require( - addressToBytes32(msg.sender) == depositInfo.mintRecipient, - "caller must be mintRecipient" - ); + 3. Load configuration and contracts: - // confirm that the caller passed the correct message pair - require( - verifyCircleMessage( - params.circleBridgeMessage, - depositInfo.sourceDomain, - depositInfo.targetDomain, - depositInfo.nonce - ), - "invalid message pair" - ); - // call the circle bridge to mint tokens to the recipient - bool success = circleTransmitter().receiveMessage( - params.circleBridgeMessage, - params.circleAttestation - ); - require(success, "CIRCLE_INTEGRATION: failed to mint tokens"); + ```typescript + const configPath = path.resolve(__dirname, '../deploy-config/config.json'); + return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; +} - // emit Redeemed event - emit Redeemed( - verifiedMessage.emitterChainId, - verifiedMessage.emitterAddress, - verifiedMessage.sequence - ); - } +function loadDeployedContracts(): DeployedContracts { + const contractsPath = path.resolve( + __dirname, + '../deploy-config/contracts.json' + ); + if ( + !fs.existsSync(contractsPath) || + fs.readFileSync(contractsPath, 'utf8').trim() === '' + ) { + console.error( + 'No contracts found. Please deploy contracts first before transferring tokens.' + ); + process.exit(1); + } + return JSON.parse(fs.readFileSync(contractsPath, 'utf8')); +} + ``` - function verifyWormholeRedeemMessage( - bytes memory encodedMessage - ) internal returns (IWormhole.VM memory) { - require(evmChain() == block.chainid, "invalid evm chain"); + These functions load the network and contract details that were saved during deployment. - // parse and verify the Wormhole core message - ( - IWormhole.VM memory verifiedMessage, - bool valid, - string memory reason - ) = wormhole().parseAndVerifyVM(encodedMessage); + 4. Allow users to select source and target chains: - // confirm that the core layer verified the message - require(valid, reason); + Refer to the deployed contracts and create logic as desired. In our example, we made this process interactive, allowing users to select the source and target chains from all the historically deployed contracts. This interactive approach helps ensure the correct chains are selected for the token transfer. - // verify that this message was emitted by a trusted contract - require(verifyEmitter(verifiedMessage), "unknown emitter"); + ```typescript + chainId: number; + networkName: string; +} { + const sourceOptions = Object.entries(deployedContracts).filter( + ([, contracts]) => contracts.CrossChainSender + ); - // revert if this message has been consumed already - require( - !isMessageConsumed(verifiedMessage.hash), - "message already consumed" - ); - consumeMessage(verifiedMessage.hash); + if (sourceOptions.length === 0) { + console.error('No source chains available with CrossChainSender deployed.'); + process.exit(1); + } - return verifiedMessage; - } + console.log('\nSelect the source chain:'); + sourceOptions.forEach(([chainId, contracts], index) => { + console.log(`${index + 1}: ${contracts.networkName}`); + }); - function verifyEmitter( - IWormhole.VM memory vm - ) internal view returns (bool) { - // verify that the sender of the wormhole message is a trusted - return (getRegisteredEmitter(vm.emitterChainId) == vm.emitterAddress && - vm.emitterAddress != bytes32(0)); - } + const selectedIndex = + readlineSync.questionInt(`\nEnter the number for the source chain: `) - 1; + return { + chainId: Number(sourceOptions[selectedIndex][0]), + networkName: sourceOptions[selectedIndex][1].networkName, + }; +} - function verifyCircleMessage( - bytes memory circleMessage, - uint32 sourceDomain, - uint32 targetDomain, - uint64 nonce - ) internal pure returns (bool) { - // parse the circle bridge message inline - uint32 circleSourceDomain = circleMessage.toUint32(4); - uint32 circleTargetDomain = circleMessage.toUint32(8); - uint64 circleNonce = circleMessage.toUint64(12); +function selectTargetChain(deployedContracts: DeployedContracts): { + chainId: number; + networkName: string; +} { + const targetOptions = Object.entries(deployedContracts).filter( + ([, contracts]) => contracts.CrossChainReceiver + ); - // confirm that both the Wormhole message and Circle message share the same transfer info - return (sourceDomain == circleSourceDomain && - targetDomain == circleTargetDomain && - nonce == circleNonce); - } + if (targetOptions.length === 0) { + console.error( + 'No target chains available with CrossChainReceiver deployed.' + ); + process.exit(1); + } - /** - * @notice Fetches the local token address given an address and domain from - * a different chain. - * @param sourceDomain Circle domain for the sending chain. - * @param sourceToken Address of the token for the sending chain. - * @return Address bytes32 formatted address of the `sourceToken` on this chain. - */ - function fetchLocalTokenAddress( - uint32 sourceDomain, - bytes32 sourceToken - ) public view returns (bytes32) { - return - addressToBytes32( - circleTokenMinter().remoteTokensToLocalTokens( - keccak256(abi.encodePacked(sourceDomain, sourceToken)) - ) - ); - } + console.log('\nSelect the target chain:'); + targetOptions.forEach(([chainId, contracts], index) => { + console.log(`${index + 1}: ${contracts.networkName}`); + }); - /** - * @notice Converts type address to bytes32 (left-zero-padded) - * @param address_ Address to convert to bytes32 - * @return Address bytes32 - */ - function addressToBytes32(address address_) public pure returns (bytes32) { - return bytes32(uint256(uint160(address_))); - } + const selectedIndex = + readlineSync.questionInt(`\nEnter the number for the target chain: `) - 1; + return { + chainId: Number(targetOptions[selectedIndex][0]), + networkName: targetOptions[selectedIndex][1].networkName, + }; } - ``` + ``` -The functions provided by the Circle Integration contract are as follows: +2. **Implement the token transfer logic** -- **`transferTokensWithPayload`** - calls the Circle Bridge contract to burn Circle-supported tokens. It emits a Wormhole message containing a user-specified payload with instructions for what to do with the Circle-supported assets once they have been minted on the target chain + 1. Start the `main` function: + + ```typescript + const chains = loadConfig(); + const deployedContracts = loadDeployedContracts(); - ??? interface "Parameters" + // Select the source chain (only show chains with CrossChainSender deployed) + const { chainId: sourceChainId, networkName: sourceNetworkName } = + selectSourceChain(deployedContracts); + const sourceChain = chains.find((chain) => chain.chainId === sourceChainId)!; - `transferParams` ++"TransferParameters"++ + // Select the target chain (only show chains with CrossChainReceiver deployed) + const { chainId: targetChainId, networkName: targetNetworkName } = + selectTargetChain(deployedContracts); + const targetChain = chains.find((chain) => chain.chainId === targetChainId)!; - A tuple containing the parameters for the transfer. + // Set up providers and wallets + const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); - ??? child "`TransferParameters` struct" + // Load the ABI from the JSON file (use the compiled ABI from Forge or Hardhat) + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' + ), + 'utf8' + ) + ); - `token` ++"address"++ + const abi = CrossChainSenderArtifact.abi; - Address of the token to be burned. + // Create the contract instance using the full ABI + const CrossChainSender = new ethers.Contract( + deployedContracts[sourceChainId].CrossChainSender!, + abi, + wallet + ); + ``` + + The `main` function is where the token transfer logic will reside. It loads the chain and contract details, sets up the wallet and provider, and loads the `CrossChainSender` contract. - --- - - `amount` ++"uint256"++ - - Amount of the token to be burned. + 2. Ask the user for token transfer details: - --- + You'll now ask the user for the token contract address, the recipient address on the target chain, and the amount of tokens to transfer. - `targetChain` ++"uint16"++ + ```typescript + 'Enter the token contract address: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on the target chain: ' + ); - Wormhole chain ID of the target blockchain. + // Get the token contract + const tokenContractDecimals = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + ], + wallet + ); - --- + // Fetch the token decimals + const decimals = await tokenContractDecimals.decimals(); - `mintRecipient` ++"bytes32"++ + // Get the amount from the user, then parse it according to the token's decimals + const amount = ethers.parseUnits( + readlineSync.question('Enter the amount of tokens to transfer: '), + decimals + ); + ``` - The recipient wallet or contract address on the target chain. + This section of the script prompts the user for the token contract address and the recipient's address, fetches the token's decimal value, and parses the amount accordingly. - --- + 3. Initiate the transfer: - `batchId` ++"uint32"++ + Finally, initiate the cross-chain transfer and log the details. - The ID for Wormhole message batching. + ```typescript + // Approve the CrossChainSender contract to transfer tokens on behalf of the user + const tokenContract = new ethers.Contract( + tokenAddress, + ['function approve(address spender, uint256 amount) public returns (bool)'], + wallet + ); - --- + const approveTx = await tokenContract.approve( + deployedContracts[sourceChainId].CrossChainSender!, + amount + ); + await approveTx.wait(); + console.log(`Approved tokens for cross-chain transfer.`); - `payload` ++"bytes"++ + // Initiate the cross-chain transfer + const transferTx = await CrossChainSender.sendCrossChainDeposit( + targetChainId, + deployedContracts[targetChainId].CrossChainReceiver!, + recipientAddress, + amount, + tokenAddress, + { value: cost } // Attach the necessary fee for cross-chain transfer + ); + await transferTx.wait(); + console.log( + `Transfer initiated from ${sourceNetworkName} to ${targetNetworkName}. Transaction Hash: ${transferTx.hash}` + ); +} + ``` - Arbitrary payload to be delivered to the target chain via Wormhole. + This part of the script first approves the token transfer, then initiates the cross-chain transfer using the `CrossChainSender` contract, and finally logs the transaction hash for the user to track. - ??? interface "Returns" + 4. Finalize the script: - `messageSequence` ++"uint64"++ + ```typescript + console.error(error); + process.exit(1); +}); + ``` - Wormhole sequence number for this contract. + This section finalizes the script by calling the `main` function and handling any errors that may occur during the token transfer process. -- `redeemTokensWithPayload` - verifies the Wormhole message from the source chain and verifies that the passed Circle Bridge message is valid. It calls the Circle Bridge contract by passing the Circle message and attestation to the `receiveMessage` function, which is responsible for minting tokens to the specified mint recipient. It also verifies that the caller is the specified mint recipient to ensure atomic execution of the additional instructions in the Wormhole message +You can find the full code for the `transfer.ts` file below: - ??? interface "Parameters" +??? code "transfer.ts" - `params` ++"RedeemParameters"++ + ```solidity + import { ethers } from 'ethers'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as dotenv from 'dotenv'; +import readlineSync from 'readline-sync'; - A tuple containing the parameters for the redemption. +dotenv.config(); - ??? child "`RedeemParameters` struct" +interface ChainConfig { + description: string; + chainId: number; + rpc: string; + tokenBridge: string; + wormholeRelayer: string; + wormhole: string; +} - `encodedWormholeMessage` ++"bytes"++ +interface DeployedContracts { + [chainId: number]: { + networkName: string; + CrossChainSender?: string; + CrossChainReceiver?: string; + deployedAt: string; + }; +} - Wormhole message emitted by a registered contract including information regarding the token burn on the source chain and an arbitrary message. +function loadConfig(): ChainConfig[] { + const configPath = path.resolve(__dirname, '../deploy-config/config.json'); + return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; +} - --- +function loadDeployedContracts(): DeployedContracts { + const contractsPath = path.resolve( + __dirname, + '../deploy-config/contracts.json' + ); + if ( + !fs.existsSync(contractsPath) || + fs.readFileSync(contractsPath, 'utf8').trim() === '' + ) { + console.error( + 'No contracts found. Please deploy contracts first before transferring tokens.' + ); + process.exit(1); + } + return JSON.parse(fs.readFileSync(contractsPath, 'utf8')); +} - `circleBridgeMessage` ++"bytes"++ +function selectSourceChain(deployedContracts: DeployedContracts): { + chainId: number; + networkName: string; +} { + const sourceOptions = Object.entries(deployedContracts).filter( + ([, contracts]) => contracts.CrossChainSender + ); - Message emitted by Circle Bridge contract with information regarding the token burn on the source chain. + if (sourceOptions.length === 0) { + console.error('No source chains available with CrossChainSender deployed.'); + process.exit(1); + } - --- + console.log('\nSelect the source chain:'); + sourceOptions.forEach(([chainId, contracts], index) => { + console.log(`${index + 1}: ${contracts.networkName}`); + }); - `circleAttestation` ++"bytes"++ + const selectedIndex = + readlineSync.questionInt(`\nEnter the number for the source chain: `) - 1; + return { + chainId: Number(sourceOptions[selectedIndex][0]), + networkName: sourceOptions[selectedIndex][1].networkName, + }; +} - Serialized EC signature attesting the cross-chain transfer. +function selectTargetChain(deployedContracts: DeployedContracts): { + chainId: number; + networkName: string; +} { + const targetOptions = Object.entries(deployedContracts).filter( + ([, contracts]) => contracts.CrossChainReceiver + ); - ??? interface "Returns" + if (targetOptions.length === 0) { + console.error( + 'No target chains available with CrossChainReceiver deployed.' + ); + process.exit(1); + } - `depositInfo` ++"DepositWithPayload"++ + console.log('\nSelect the target chain:'); + targetOptions.forEach(([chainId, contracts], index) => { + console.log(`${index + 1}: ${contracts.networkName}`); + }); - Information about the deposit. + const selectedIndex = + readlineSync.questionInt(`\nEnter the number for the target chain: `) - 1; + return { + chainId: Number(targetOptions[selectedIndex][0]), + networkName: targetOptions[selectedIndex][1].networkName, + }; +} - ??? child "`DepositWithPayload` struct" +async function main() { + const chains = loadConfig(); + const deployedContracts = loadDeployedContracts(); - `token` ++"bytes32"++ + // Select the source chain (only show chains with CrossChainSender deployed) + const { chainId: sourceChainId, networkName: sourceNetworkName } = + selectSourceChain(deployedContracts); + const sourceChain = chains.find((chain) => chain.chainId === sourceChainId)!; - Address (`bytes32` left-zero-padded) of token to be minted. + // Select the target chain (only show chains with CrossChainReceiver deployed) + const { chainId: targetChainId, networkName: targetNetworkName } = + selectTargetChain(deployedContracts); + const targetChain = chains.find((chain) => chain.chainId === targetChainId)!; - --- + // Set up providers and wallets + const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); + const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); - `amount` ++"uint256"++ + // Load the ABI from the JSON file (use the compiled ABI from Forge or Hardhat) + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync( + path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' + ), + 'utf8' + ) + ); - Amount of tokens to be minted. - - --- + const abi = CrossChainSenderArtifact.abi; - `sourceDomain` ++"uint32"++ + // Create the contract instance using the full ABI + const CrossChainSender = new ethers.Contract( + deployedContracts[sourceChainId].CrossChainSender!, + abi, + wallet + ); - Circle domain for the source chain. + // Display the selected chains + console.log( + `\nInitiating transfer from ${sourceNetworkName} to ${targetNetworkName}.` + ); - --- + // Ask the user for token transfer details + const tokenAddress = readlineSync.question( + 'Enter the token contract address: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on the target chain: ' + ); - `targetDomain` ++"uint32"++ + // Get the token contract + const tokenContractDecimals = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + ], + wallet + ); - Circle domain for the target chain. + // Fetch the token decimals + const decimals = await tokenContractDecimals.decimals(); - --- + // Get the amount from the user, then parse it according to the token's decimals + const amount = ethers.parseUnits( + readlineSync.question('Enter the amount of tokens to transfer: '), + decimals + ); - `nonce` ++"uint64"++ + // Calculate the cross-chain transfer cost + const cost = await CrossChainSender.quoteCrossChainDeposit(targetChainId); - Circle sequence number for the transfer. + // Approve the CrossChainSender contract to transfer tokens on behalf of the user + const tokenContract = new ethers.Contract( + tokenAddress, + ['function approve(address spender, uint256 amount) public returns (bool)'], + wallet + ); - --- + const approveTx = await tokenContract.approve( + deployedContracts[sourceChainId].CrossChainSender!, + amount + ); + await approveTx.wait(); + console.log(`Approved tokens for cross-chain transfer.`); - `fromAddress` ++"bytes32"++ + // Initiate the cross-chain transfer + const transferTx = await CrossChainSender.sendCrossChainDeposit( + targetChainId, + deployedContracts[targetChainId].CrossChainReceiver!, + recipientAddress, + amount, + tokenAddress, + { value: cost } // Attach the necessary fee for cross-chain transfer + ); + await transferTx.wait(); + console.log( + `Transfer initiated from ${sourceNetworkName} to ${targetNetworkName}. Transaction Hash: ${transferTx.hash}` + ); +} - Source Circle Integration contract caller's address. +main().catch((error) => { + console.error(error); + process.exit(1); +}); + ``` - --- +### Transfer Tokens - `mintRecipient` ++"bytes32"++ +Now that your transfer script is ready, it’s time to execute it and perform a cross-chain token transfer. - Recipient of minted tokens (must be caller of this contract). +1. **Run the transfer script** - --- + Open your terminal and run the transfer script: - `payload` ++"bytes"++ + ```bash + npx ts-node script/transfer.ts + ``` - Arbitrary Wormhole message payload. + This command will start the script, prompting you to select the source and target chains, input the token address, recipient address, and the amount of tokens to transfer. - ??? interface "Emits" +2. **Follow the prompts** - the script will guide you through selecting the source and target chains and entering the necessary details for the token transfer. Once you provide all the required information, the script will initiate the token transfer - `Redeemed` - event emitted when Circle-supported assets have been minted to the `mintRecipient` +3. **Verify the transaction** - after running the script, you should see a confirmation message with the transaction hash. You can use this transaction hash to check the transfer status on the respective blockchain explorers - ??? child "Event arguments" +You can verify the transaction on the [Wormhole Explorer](https://wormholescan.io/){target=\_balnk} using the link provided in the terminal output. This explorer also offers the option to add the transferred token to your MetaMask wallet automatically. - `emitterChainId` ++"uint16"++ +If you followed the logic provided in the `transfer.ts` file above, your terminal output should look something like this: - Wormhole chain ID of emitter contract on source chain. +
+npx ts-node transfer.ts + > cross-chain-token-transfer@1.0.0 transfer + > npx ts-node script/transfer.ts + + Select the source chain: + 1: Avalanche testnet fuji + 2: Celo Testnet + + Enter the number for the SOURCE chain: 1 + + Select the target chain: + 1: Avalanche testnet fuji + 2: Celo Testnet + + Enter the number for the TARGET chain: 2 + + Initiating transfer from Avalanche testnet fuji to Celo Testnet + Enter the token contract address: 0x5425890298aed601595a70ab815c96711a31bc65 + Enter the recipient address on the target chain: INSERT_YOUR_WALLET_ADDRESS + Enter the amount of tokens to transfer: 2 + Approved tokens for cross-chain transfer. + Transfer initiated from Avalanche testnet fuji to Celo Testnet. Transaction Hash: 0x4a923975d955c1f226a1c2f61a1a0fa1ab1a9e229dc29ceaeadf8ef40acd071f + +
- --- +!!! note + In this example, we demonstrated a token transfer from the Avalanche Fuji Testnet to the Celo Alfajores Testnet. We sent two units of USDC Testnet tokens using the token contract address `0x5425890298aed601595a70ab815c96711a31bc65`. You can replace these details with those relevant to your project or use the same for testing purposes. - `emitterAddress` ++"bytes32"++ +## Resources - Address (`bytes32` zero-left-padded) of emitter on source chain. +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in the [Cross-Chain Token Transfers GitHub repository](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank}. The repository includes all the scripts, contracts, and configurations needed to deploy and transfer tokens across chains using the Wormhole protocol. - --- +## Conclusion - `sequence` ++"uint64"++ +Congratulations! You've successfully built and deployed a cross-chain token transfer system using Solidity and the Wormhole protocol. You've learned how to: - Sequence of Wormhole message used to mint tokens. + - Set up a new Solidity project using Foundry + - Develop smart contracts to send and receive tokens across chains + - Write deployment scripts to manage and deploy contracts on different networks +--- END CONTENT --- -## Circle's CCTP Contracts +Doc-Content: https://wormhole.com/docs/products/messaging/tutorials/replace-signatures/ +--- BEGIN CONTENT --- +--- +title: Replace Outdated Signatures in VAAs +description: Learn how to fetch, validate, and replace outdated signatures in Wormhole VAAs using Wormholescan and the Wormhole SDK to ensure seamless processing. +--- -Three key contracts power Circle's CCTP: +# Replace Outdated Signatures in VAAs -- **`TokenMessenger`** - the entry point for cross-chain USDC transfers, routing messages to initiate USDC burns on the source chain, and mint USDC on the destination chain -- **`MessageTransmitter`** - handles generic message passing, sending messages from the source chain and receiving them on the destination chain -- **`TokenMinter`** - responsible for the actual minting and burning of USDC, utilizing chain-specific settings for both the burners and minters across different networks +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-vaa-signature-replacement){target=\_blank} -The following sections will examine these contracts in-depth, focusing on the methods invoked indirectly through function calls in the Wormhole Circle Integration contract. +## Introduction -!!! note - When using Wormhole's CCTP integration, you will not directly interact with these contracts. You will indirectly interact with them through the Wormhole Circle Integration contract. +Cross-chain transactions in Wormhole rely on [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank}, which contain signatures from a trusted set of validators called [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}. These signatures prove that the network approved an action, such as a token transfer. -These contracts can be found in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/){target=\_blank} on GitHub. +However, the set of Guardians changes over time. If a user generates a transaction and waits too long before redeeming it, the Guardian set may have already changed. This means the VAA will contain outdated signatures from Guardians, who are no longer part of the network, causing the transaction to fail. -### Token Messenger Contract +Instead of discarding these VAAs, we can fetch updated signatures and replace the outdated ones to ensure smooth processing. -The Token Messenger contract enables cross-chain USDC transfers by coordinating message exchanges between blockchains. It works alongside the Message Transmitter contract to relay messages for burning USDC on a source chain and minting it on a destination chain. The contract emits events to track both the burning of tokens and their subsequent minting on the destination chain. +In this tutorial, you'll build a script from scratch to: -To ensure secure communication, the Token Messenger restricts message handling to registered remote Token Messenger contracts only. It verifies the proper conditions for token burning and manages local and remote minters using chain-specific settings. +- Fetch a VAA from [Wormholescan](https://wormholescan.io/#/developers/api-doc){target=\_blank} +- Validate its signatures against the latest Guardian set +- Replace outdated signatures using the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} +- Output a valid VAA ready for submission -Additionally, the contract provides methods for updating or replacing previously sent burn messages, adding or removing remote Token Messenger contracts, and managing the minting process for cross-chain transfers. +By the end, you'll have a script that ensures VAAs remain valid and processable, avoiding transaction failures. -??? code "Token Messenger contract" - ```solidity - /* - * Copyright (c) 2022, Circle Internet Financial Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -pragma solidity 0.7.6; +## Prerequisites -import "./interfaces/IMessageHandler.sol"; -import "./interfaces/ITokenMinter.sol"; -import "./interfaces/IMintBurnToken.sol"; -import "./interfaces/IMessageTransmitter.sol"; -import "./messages/BurnMessage.sol"; -import "./messages/Message.sol"; -import "./roles/Rescuable.sol"; +Before you begin, ensure you have the following: -/** - * @title TokenMessenger - * @notice Sends messages and receives messages to/from MessageTransmitters - * and to/from TokenMinters - */ -contract TokenMessenger is IMessageHandler, Rescuable { - // ============ Events ============ - /** - * @notice Emitted when a DepositForBurn message is sent - * @param nonce unique nonce reserved by message - * @param burnToken address of token burnt on source domain - * @param amount deposit amount - * @param depositor address where deposit is transferred from - * @param mintRecipient address receiving minted tokens on destination domain as bytes32 - * @param destinationDomain destination domain - * @param destinationTokenMessenger address of TokenMessenger on destination domain as bytes32 - * @param destinationCaller authorized caller as bytes32 of receiveMessage() on destination domain, if not equal to bytes32(0). - * If equal to bytes32(0), any address can call receiveMessage(). - */ - event DepositForBurn( - uint64 indexed nonce, - address indexed burnToken, - uint256 amount, - address indexed depositor, - bytes32 mintRecipient, - uint32 destinationDomain, - bytes32 destinationTokenMessenger, - bytes32 destinationCaller - ); + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine + - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally - /** - * @notice Emitted when tokens are minted - * @param mintRecipient recipient address of minted tokens - * @param amount amount of minted tokens - * @param mintToken contract address of minted token - */ - event MintAndWithdraw( - address indexed mintRecipient, - uint256 amount, - address indexed mintToken - ); +## Project Setup - /** - * @notice Emitted when a remote TokenMessenger is added - * @param domain remote domain - * @param tokenMessenger TokenMessenger on remote domain - */ - event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger); +In this section, you will create the directory, initialize a Node.js project, install dependencies, and configure TypeScript. - /** - * @notice Emitted when a remote TokenMessenger is removed - * @param domain remote domain - * @param tokenMessenger TokenMessenger on remote domain - */ - event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger); +1. **Create the project** - set up the directory and navigate into it - /** - * @notice Emitted when the local minter is added - * @param localMinter address of local minter - * @notice Emitted when the local minter is added - */ - event LocalMinterAdded(address localMinter); + ```bash + mkdir wormhole-scan-api-demo + cd wormhole-scan-api-demo + ``` - /** - * @notice Emitted when the local minter is removed - * @param localMinter address of local minter - * @notice Emitted when the local minter is removed - */ - event LocalMinterRemoved(address localMinter); +2. **Initialize a Node.js project** - generate a `package.json` file - // ============ Libraries ============ - using TypedMemView for bytes; - using TypedMemView for bytes29; - using BurnMessage for bytes29; - using Message for bytes29; + ```bash + npm init -y + ``` - // ============ State Variables ============ - // Local Message Transmitter responsible for sending and receiving messages to/from remote domains - IMessageTransmitter public immutable localMessageTransmitter; +3. **Set up TypeScript** - create a `tsconfig.json` file - // Version of message body format - uint32 public immutable messageBodyVersion; + ```bash + touch tsconfig.json + ``` - // Minter responsible for minting and burning tokens on the local domain - ITokenMinter public localMinter; - - // Valid TokenMessengers on remote domains - mapping(uint32 => bytes32) public remoteTokenMessengers; + Then, add the following configuration: - // ============ Modifiers ============ - /** - * @notice Only accept messages from a registered TokenMessenger contract on given remote domain - * @param domain The remote domain - * @param tokenMessenger The address of the TokenMessenger contract for the given remote domain - */ - modifier onlyRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) { - require( - _isRemoteTokenMessenger(domain, tokenMessenger), - "Remote TokenMessenger unsupported" - ); - _; + ```json title="tsconfig.json" + { + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true } +} + ``` - /** - * @notice Only accept messages from the registered message transmitter on local domain - */ - modifier onlyLocalMessageTransmitter() { - // Caller must be the registered message transmitter for this domain - require(_isLocalMessageTransmitter(), "Invalid message transmitter"); - _; - } +4. **Install dependencies** - add the required packages - // ============ Constructor ============ - /** - * @param _messageTransmitter Message transmitter address - * @param _messageBodyVersion Message body version - */ - constructor(address _messageTransmitter, uint32 _messageBodyVersion) { - require( - _messageTransmitter != address(0), - "MessageTransmitter not set" - ); - localMessageTransmitter = IMessageTransmitter(_messageTransmitter); - messageBodyVersion = _messageBodyVersion; - } + ```bash + npm install @wormhole-foundation/sdk axios web3 tsx @types/node + ``` - // ============ External Functions ============ - /** - * @notice Deposits and burns tokens from sender to be minted on destination domain. - * Emits a `DepositForBurn` event. - * @dev reverts if: - * - given burnToken is not supported - * - given destinationDomain has no TokenMessenger registered - * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance - * to this contract is less than `amount`. - * - burn() reverts. For example, if `amount` is 0. - * - MessageTransmitter returns false or reverts. - * @param amount amount of tokens to burn - * @param destinationDomain destination domain - * @param mintRecipient address of mint recipient on destination domain - * @param burnToken address of contract to burn deposited tokens, on local domain - * @return _nonce unique nonce reserved by message - */ - function depositForBurn( - uint256 amount, - uint32 destinationDomain, - bytes32 mintRecipient, - address burnToken - ) external returns (uint64 _nonce) { - return - _depositForBurn( - amount, - destinationDomain, - mintRecipient, - burnToken, - // (bytes32(0) here indicates that any address can call receiveMessage() - // on the destination domain, triggering mint to specified `mintRecipient`) - bytes32(0) - ); - } + - `@wormhole-foundation/sdk` - handles VAAs and cross-chain interactions + - `axios` - makes HTTP requests to the Wormholescan API + - `web3` - interacts with Ethereum transactions and contracts + - `tsx` - executes TypeScript files without compilation + - `@types/node` - provides Node.js type definitions - /** - * @notice Deposits and burns tokens from sender to be minted on destination domain. The mint - * on the destination domain must be called by `destinationCaller`. - * WARNING: if the `destinationCaller` does not represent a valid address as bytes32, then it will not be possible - * to broadcast the message on the destination domain. This is an advanced feature, and the standard - * depositForBurn() should be preferred for use cases where a specific destination caller is not required. - * Emits a `DepositForBurn` event. - * @dev reverts if: - * - given destinationCaller is zero address - * - given burnToken is not supported - * - given destinationDomain has no TokenMessenger registered - * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance - * to this contract is less than `amount`. - * - burn() reverts. For example, if `amount` is 0. - * - MessageTransmitter returns false or reverts. - * @param amount amount of tokens to burn - * @param destinationDomain destination domain - * @param mintRecipient address of mint recipient on destination domain - * @param burnToken address of contract to burn deposited tokens, on local domain - * @param destinationCaller caller on the destination domain, as bytes32 - * @return nonce unique nonce reserved by message - */ - function depositForBurnWithCaller( - uint256 amount, - uint32 destinationDomain, - bytes32 mintRecipient, - address burnToken, - bytes32 destinationCaller - ) external returns (uint64 nonce) { - // Destination caller must be nonzero. To allow any destination caller, use depositForBurn(). - require(destinationCaller != bytes32(0), "Invalid destination caller"); +5. **Create the project structure** - set up the required directories and files - return - _depositForBurn( - amount, - destinationDomain, - mintRecipient, - burnToken, - destinationCaller - ); - } + ```bash + mkdir -p src/config && touch src/config/constants.ts src/config/layouts.ts + mkdir -p src/helpers && touch src/helpers/vaaHelper.ts + mkdir -p src/scripts && touch scripts/replaceSignatures.ts + ``` - /** - * @notice Replace a BurnMessage to change the mint recipient and/or - * destination caller. Allows the sender of a previous BurnMessage - * (created by depositForBurn or depositForBurnWithCaller) - * to send a new BurnMessage to replace the original. - * The new BurnMessage will reuse the amount and burn token of the original, - * without requiring a new deposit. - * @dev The new message will reuse the original message's nonce. For a - * given nonce, all replacement message(s) and the original message are - * valid to broadcast on the destination domain, until the first message - * at the nonce confirms, at which point all others are invalidated. - * Note: The msg.sender of the replaced message must be the same as the - * msg.sender of the original message. - * @param originalMessage original message bytes (to replace) - * @param originalAttestation original attestation bytes - * @param newDestinationCaller the new destination caller, which may be the - * same as the original destination caller, a new destination caller, or an empty - * destination caller (bytes32(0), indicating that any destination caller is valid.) - * @param newMintRecipient the new mint recipient, which may be the same as the - * original mint recipient, or different. - */ - function replaceDepositForBurn( - bytes calldata originalMessage, - bytes calldata originalAttestation, - bytes32 newDestinationCaller, - bytes32 newMintRecipient - ) external { - bytes29 _originalMsg = originalMessage.ref(0); - _originalMsg._validateMessageFormat(); - bytes29 _originalMsgBody = _originalMsg._messageBody(); - _originalMsgBody._validateBurnMessageFormat(); + - **`src/config/*`** - stores public configuration variables and layouts for serializing and deserializing data structures + - **`src/helpers/*`** - contains utility functions + - **`src/scripts/*`** - contains scripts for fetching and replacing signatures - bytes32 _originalMsgSender = _originalMsgBody._getMessageSender(); - // _originalMsgSender must match msg.sender of original message - require( - msg.sender == Message.bytes32ToAddress(_originalMsgSender), - "Invalid sender for message" - ); - require( - newMintRecipient != bytes32(0), - "Mint recipient must be nonzero" - ); +6. **Set variables** - define key constants in `src/config/constants.ts` - bytes32 _burnToken = _originalMsgBody._getBurnToken(); - uint256 _amount = _originalMsgBody._getAmount(); + ```bash title="src/config/constants.ts" + export const RPC = 'https://ethereum-rpc.publicnode.com'; - bytes memory _newMessageBody = BurnMessage._formatMessage( - messageBodyVersion, - _burnToken, - newMintRecipient, - _amount, - _originalMsgSender - ); +export const ETH_CORE = + '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B'.toLowerCase(); - localMessageTransmitter.replaceMessage( - originalMessage, - originalAttestation, - _newMessageBody, - newDestinationCaller - ); +export const WORMHOLESCAN_API = 'https://api.wormholescan.io/v1'; - emit DepositForBurn( - _originalMsg._nonce(), - Message.bytes32ToAddress(_burnToken), - _amount, - msg.sender, - newMintRecipient, - _originalMsg._destinationDomain(), - _originalMsg._recipient(), - newDestinationCaller - ); - } +export const LOG_MESSAGE_PUBLISHED_TOPIC = + '0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2'; - /** - * @notice Handles an incoming message received by the local MessageTransmitter, - * and takes the appropriate action. For a burn message, mints the - * associated token to the requested recipient on the local domain. - * @dev Validates the local sender is the local MessageTransmitter, and the - * remote sender is a registered remote TokenMessenger for `remoteDomain`. - * @param remoteDomain The domain where the message originated from. - * @param sender The sender of the message (remote TokenMessenger). - * @param messageBody The message body bytes. - * @return success Bool, true if successful. - */ - function handleReceiveMessage( - uint32 remoteDomain, - bytes32 sender, - bytes calldata messageBody - ) - external - override - onlyLocalMessageTransmitter - onlyRemoteTokenMessenger(remoteDomain, sender) - returns (bool) - { - bytes29 _msg = messageBody.ref(0); - _msg._validateBurnMessageFormat(); - require( - _msg._getVersion() == messageBodyVersion, - "Invalid message body version" - ); +export const TXS = [ + '0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367', + '0x3c989a6bb40dcd4719453fbe7bbac420f23962c900ae75793124fc9cc614368c', +]; + ``` - bytes32 _mintRecipient = _msg._getMintRecipient(); - bytes32 _burnToken = _msg._getBurnToken(); - uint256 _amount = _msg._getAmount(); + - **`RPC`** - endpoint for interacting with an Ethereum RPC node + - **`ETH_CORE`** - [Wormhole's Core Contract address on Ethereum](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} responsible for verifying VAAs + - **`WORMHOLESCAN_API`** - base URL for querying the Wormholescan API to fetch VAA data and Guardian sets + - **`LOG_MESSAGE_PUBLISHED_TOPIC`** - the event signature hash for `LogMessagePublished`, a Wormhole contract event that signals when a VAA has been emitted. This is used to identify relevant logs in transaction receipts + - **`TXS`** - list of example transaction hashes that will be used for testing - ITokenMinter _localMinter = _getLocalMinter(); +7. **Define data structure for working with VAAs** - specify the ABI for the Wormhole Core Contract's `parseAndVerifyVM` function, which parses and verifies VAAs. Defining the data structure, also referred to as a [layout](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank}, for this function ensures accurate decoding and validation of VAAs - _mintAndWithdraw( - address(_localMinter), - remoteDomain, - _burnToken, - Message.bytes32ToAddress(_mintRecipient), - _amount - ); + ```typescript title="src/config/layouts.ts" + export const PARSE_AND_VERIFY_VM_ABI = { + inputs: [{ internalType: 'bytes', name: 'encodedVM', type: 'bytes' }], + name: 'parseAndVerifyVM', + outputs: [ + { + components: [ + { internalType: 'uint8', name: 'version', type: 'uint8' }, + { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, + { internalType: 'uint32', name: 'nonce', type: 'uint32' }, + { internalType: 'uint16', name: 'emitterChainId', type: 'uint16' }, + { internalType: 'bytes32', name: 'emitterAddress', type: 'bytes32' }, + { internalType: 'uint64', name: 'sequence', type: 'uint64' }, + { internalType: 'uint8', name: 'consistencyLevel', type: 'uint8' }, + { internalType: 'bytes', name: 'payload', type: 'bytes' }, + { internalType: 'uint32', name: 'guardianSetIndex', type: 'uint32' }, + { + components: [ + { internalType: 'bytes32', name: 'r', type: 'bytes32' }, + { internalType: 'bytes32', name: 's', type: 'bytes32' }, + { internalType: 'uint8', name: 'v', type: 'uint8' }, + { internalType: 'uint8', name: 'guardianIndex', type: 'uint8' }, + ], + internalType: 'struct Structs.Signature[]', + name: 'signatures', + type: 'tuple[]', + }, + { internalType: 'bytes32', name: 'hash', type: 'bytes32' }, + ], + internalType: 'struct Structs.VM', + name: 'vm', + type: 'tuple', + }, + { internalType: 'bool', name: 'valid', type: 'bool' }, + { internalType: 'string', name: 'reason', type: 'string' }, + ], + stateMutability: 'view', + type: 'function', +}; + ``` - return true; - } +## Create VAA Handling Functions - /** - * @notice Add the TokenMessenger for a remote domain. - * @dev Reverts if there is already a TokenMessenger set for domain. - * @param domain Domain of remote TokenMessenger. - * @param tokenMessenger Address of remote TokenMessenger as bytes32. - */ - function addRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) - external - onlyOwner - { - require(tokenMessenger != bytes32(0), "bytes32(0) not allowed"); +In this section, we'll create a series of helper functions in the `src/helpers/vaaHelper.ts` file that will retrieve and verify VAAs and fetch and replace outdated Guardian signatures to generate a correctly signed VAA. - require( - remoteTokenMessengers[domain] == bytes32(0), - "TokenMessenger already set" - ); +To get started, import the necessary dependencies: - remoteTokenMessengers[domain] = tokenMessenger; - emit RemoteTokenMessengerAdded(domain, tokenMessenger); - } +```typescript title="src/helpers/vaaHelper.ts" +import { eth } from 'web3'; +import { + deserialize, + serialize, + VAA, + Signature, +} from '@wormhole-foundation/sdk'; +import { + RPC, + ETH_CORE, + LOG_MESSAGE_PUBLISHED_TOPIC, + WORMHOLESCAN_API, +} from '../config/constants'; +import { PARSE_AND_VERIFY_VM_ABI } from '../config/layouts'; +``` - /** - * @notice Remove the TokenMessenger for a remote domain. - * @dev Reverts if there is no TokenMessenger set for `domain`. - * @param domain Domain of remote TokenMessenger - */ - function removeRemoteTokenMessenger(uint32 domain) external onlyOwner { - // No TokenMessenger set for given remote domain. - require( - remoteTokenMessengers[domain] != bytes32(0), - "No TokenMessenger set" - ); +### Fetch a VAA ID from a Transaction - bytes32 _removedTokenMessenger = remoteTokenMessengers[domain]; - delete remoteTokenMessengers[domain]; - emit RemoteTokenMessengerRemoved(domain, _removedTokenMessenger); - } +To retrieve a VAA, we first need to get its VAA ID from a transaction hash. This ID allows us to fetch the full VAA later. +The VAA ID is structured as follows: - /** - * @notice Add minter for the local domain. - * @dev Reverts if a minter is already set for the local domain. - * @param newLocalMinter The address of the minter on the local domain. - */ - function addLocalMinter(address newLocalMinter) external onlyOwner { - require(newLocalMinter != address(0), "Zero address not allowed"); +```bash +chain/emitter/sequence +``` - require( - address(localMinter) == address(0), - "Local minter is already set." - ); + - `chain` - the [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} (Ethereum is 2) + - `emitter` - the contract address that emitted the VAA + - `sequence` - a unique identifier for the event - localMinter = ITokenMinter(newLocalMinter); +We must assemble the ID correctly since this is the format the Wormholescan API expects when querying VAAs. - emit LocalMinterAdded(newLocalMinter); - } +Follow the below steps to process the transaction logs and construct the VAA ID: - /** - * @notice Remove the minter for the local domain. - * @dev Reverts if the minter of the local domain is not set. - */ - function removeLocalMinter() external onlyOwner { - address _localMinterAddress = address(localMinter); - require(_localMinterAddress != address(0), "No local minter is set."); +1. **Get the transaction receipt** - iterate over the array of transaction hashes and fetch the receipt to access its logs - delete localMinter; - emit LocalMinterRemoved(_localMinterAddress); +2. **Find the Wormhole event** - iterate over the transaction logs and check for events emitted by the Wormhole Core contract. Look specifically for `LogMessagePublished` events, which indicate a VAA was created + +3. **Extract the emitter and sequence number** - if a matching event is found, extract the emitter address from `log.topics[1]` and remove the `0x` prefix. Then, the sequence number from `log.data` is extracted, converting it from hex to an integer + +4. **Construct the VAA ID** - format the extracted data in `chain/emitter/sequence` format + +```typescript title="src/helpers/vaaHelper.ts" +const vaaIds: string[] = []; + + for (const tx of txHashes) { + try { + const result = ( + await axios.post(RPC, { + jsonrpc: '2.0', + id: 1, + method: 'eth_getTransactionReceipt', + params: [tx], + }) + ).data.result; + + if (!result) + throw new Error(`Unable to fetch transaction receipt for ${tx}`); + + for (const log of result.logs) { + if ( + log.address === ETH_CORE && + log.topics?.[0] === LOG_MESSAGE_PUBLISHED_TOPIC + ) { + const emitter = log.topics[1].substring(2); + const seq = BigInt(log.data.substring(0, 66)).toString(); + vaaIds.push(`2/${emitter}/${seq}`); + } + } + } catch (error) { + console.error(`Error processing ${tx}:`, error); } + } - // ============ Internal Utils ============ - /** - * @notice Deposits and burns tokens from sender to be minted on destination domain. - * Emits a `DepositForBurn` event. - * @param _amount amount of tokens to burn (must be non-zero) - * @param _destinationDomain destination domain - * @param _mintRecipient address of mint recipient on destination domain - * @param _burnToken address of contract to burn deposited tokens, on local domain - * @param _destinationCaller caller on the destination domain, as bytes32 - * @return nonce unique nonce reserved by message - */ - function _depositForBurn( - uint256 _amount, - uint32 _destinationDomain, - bytes32 _mintRecipient, - address _burnToken, - bytes32 _destinationCaller - ) internal returns (uint64 nonce) { - require(_amount > 0, "Amount must be nonzero"); - require(_mintRecipient != bytes32(0), "Mint recipient must be nonzero"); + return vaaIds; +} +``` - bytes32 _destinationTokenMessenger = _getRemoteTokenMessenger( - _destinationDomain - ); +???- code "Try it out: VAA ID retrieval" + If you want to try out the function before moving forward, create a test file inside the `test` directory: - ITokenMinter _localMinter = _getLocalMinter(); - IMintBurnToken _mintBurnToken = IMintBurnToken(_burnToken); - require( - _mintBurnToken.transferFrom( - msg.sender, - address(_localMinter), - _amount - ), - "Transfer operation failed" - ); - _localMinter.burn(_burnToken, _amount); + 1. **Create the directory and file** - add a script to call `fetchVaaId` and print the result - // Format message body - bytes memory _burnMessage = BurnMessage._formatMessage( - messageBodyVersion, - Message.addressToBytes32(_burnToken), - _mintRecipient, - _amount, - Message.addressToBytes32(msg.sender) - ); + ```bash + mkdir -p test + touch test/fetchVaaId.run.ts + ``` + 2. **Add the function call** - uint64 _nonceReserved = _sendDepositForBurnMessage( - _destinationDomain, - _destinationTokenMessenger, - _destinationCaller, - _burnMessage - ); + ```typescript title="test/fetchVaaId.run.ts" + import { fetchVaaId } from '../src/helpers/vaaHelper'; +import { TXS } from '../src/config/constants'; - emit DepositForBurn( - _nonceReserved, - _burnToken, - _amount, - msg.sender, - _mintRecipient, - _destinationDomain, - _destinationTokenMessenger, - _destinationCaller - ); +const testFetchVaaId = async () => { + for (const tx of TXS) { + const vaaIds = await fetchVaaId([tx]); - return _nonceReserved; + if (vaaIds.length > 0) { + console.log(`Transaction: ${tx}`); + vaaIds.forEach((vaaId) => console.log(`VAA ID: ${vaaId}`)); + } else { + console.log(`No VAA ID found for transaction: ${tx}`); } + } +}; - /** - * @notice Sends a BurnMessage through the local message transmitter - * @dev calls local message transmitter's sendMessage() function if `_destinationCaller` == bytes32(0), - * or else calls sendMessageWithCaller(). - * @param _destinationDomain destination domain - * @param _destinationTokenMessenger address of registered TokenMessenger contract on destination domain, as bytes32 - * @param _destinationCaller caller on the destination domain, as bytes32. If `_destinationCaller` == bytes32(0), - * any address can call receiveMessage() on destination domain. - * @param _burnMessage formatted BurnMessage bytes (message body) - * @return nonce unique nonce reserved by message - */ - function _sendDepositForBurnMessage( - uint32 _destinationDomain, - bytes32 _destinationTokenMessenger, - bytes32 _destinationCaller, - bytes memory _burnMessage - ) internal returns (uint64 nonce) { - if (_destinationCaller == bytes32(0)) { - return - localMessageTransmitter.sendMessage( - _destinationDomain, - _destinationTokenMessenger, - _burnMessage - ); - } else { - return - localMessageTransmitter.sendMessageWithCaller( - _destinationDomain, - _destinationTokenMessenger, - _destinationCaller, - _burnMessage - ); - } - } - - /** - * @notice Mints tokens to a recipient - * @param _tokenMinter address of TokenMinter contract - * @param _remoteDomain domain where burned tokens originate from - * @param _burnToken address of token burned - * @param _mintRecipient recipient address of minted tokens - * @param _amount amount of minted tokens - */ - function _mintAndWithdraw( - address _tokenMinter, - uint32 _remoteDomain, - bytes32 _burnToken, - address _mintRecipient, - uint256 _amount - ) internal { - ITokenMinter _minter = ITokenMinter(_tokenMinter); - address _mintToken = _minter.mint( - _remoteDomain, - _burnToken, - _mintRecipient, - _amount - ); - - emit MintAndWithdraw(_mintRecipient, _amount, _mintToken); - } - - /** - * @notice return the remote TokenMessenger for the given `_domain` if one exists, else revert. - * @param _domain The domain for which to get the remote TokenMessenger - * @return _tokenMessenger The address of the TokenMessenger on `_domain` as bytes32 - */ - function _getRemoteTokenMessenger(uint32 _domain) - internal - view - returns (bytes32) - { - bytes32 _tokenMessenger = remoteTokenMessengers[_domain]; - require(_tokenMessenger != bytes32(0), "No TokenMessenger for domain"); - return _tokenMessenger; - } +testFetchVaaId(); + ``` - /** - * @notice return the local minter address if it is set, else revert. - * @return local minter as ITokenMinter. - */ - function _getLocalMinter() internal view returns (ITokenMinter) { - require(address(localMinter) != address(0), "Local minter is not set"); - return localMinter; - } + 3. **Run the script** - /** - * @notice Return true if the given remote domain and TokenMessenger is registered - * on this TokenMessenger. - * @param _domain The remote domain of the message. - * @param _tokenMessenger The address of the TokenMessenger on remote domain. - * @return true if a remote TokenMessenger is registered for `_domain` and `_tokenMessenger`, - * on this TokenMessenger. - */ - function _isRemoteTokenMessenger(uint32 _domain, bytes32 _tokenMessenger) - internal - view - returns (bool) - { - return - _tokenMessenger != bytes32(0) && - remoteTokenMessengers[_domain] == _tokenMessenger; - } + ```bash + npx tsx test/fetchVaaId.run.ts + ``` - /** - * @notice Returns true if the message sender is the local registered MessageTransmitter - * @return true if message sender is the registered local message transmitter - */ - function _isLocalMessageTransmitter() internal view returns (bool) { - return - address(localMessageTransmitter) != address(0) && - msg.sender == address(localMessageTransmitter); - } -} - ``` + If successful, the output will be: - This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMessenger.sol){target=\_blank} on GitHub. +
+npx tsx test/fetchVaaId.run.ts + +Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 +VAA ID: 2/0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585/164170 + +
-The functions provided by the Token Messenger contract are as follows: + If no VAA ID is found, the script will log an error message. -- **`depositForBurn`** - deposits and burns tokens from the sender to be minted on the destination domain. Minted tokens will be transferred to `mintRecipient` +### Fetch the Full VAA - ??? interface "Parameters" +Now that you have the VAA ID, we can use it to fetch the full VAA payload from the Wormholescan API. This payload contains the VAA bytes, which will later be used for signature validation. - `amount` ++"uint256"++ - - The amount of tokens to burn. +Open `src/helpers/vaaHelper.ts` and create the `fetchVaa()` function to iterate through VAA IDs and extract the `vaaBytes` payload. - --- +```typescript title="src/helpers/vaaHelper.ts" +vaaIds: string[] +): Promise<{ id: string; vaaBytes: string }[]> { + const results: { id: string; vaaBytes: string }[] = []; - `destinationDomain` ++"uint32"++ - - The network where the token will be minted after burn. + for (const id of vaaIds) { + try { + const response = await axios.get(`${WORMHOLESCAN_API}/signed_vaa/${id}`); + const vaaBytes = response.data.vaaBytes; + results.push({ id, vaaBytes }); + } catch (error) { + console.error(`Error fetching VAA for ${id}:`, error); + } + } + return results; +} +``` - --- +???- code "Try it out: VAA retrieval" + If you want to try the function before moving forward, create a script inside the `test` directory - `mintRecipient` ++"bytes32"++ - - Address of mint recipient on destination domain. + 1. **Create the script file** - --- + ```bash + touch test/fetchVaa.run.ts + ``` - `burnToken` ++"address"++ - - Address of contract to burn deposited tokens, on local domain. + 2. **Add the function call** - ??? interface "Returns" + ```typescript title="test/fetchVaa.run.ts" + import { fetchVaaId, fetchVaa } from '../src/helpers/vaaHelper'; +import { TXS } from '../src/config/constants'; - `_nonce` ++"uint64"++ - - Unique nonce reserved by message. +const testFetchVaa = async () => { + for (const tx of TXS) { + const vaaIds = await fetchVaaId([tx]); - ??? interface "Emits" + if (vaaIds.length === 0) { + console.log(`No VAA ID found for transaction: ${tx}`); + continue; + } - `DepositForBurn` - event emitted when `depositForBurn` is called. The `destinationCaller` is set to `bytes32(0)` to allow any address to call `receiveMessage` on the destination domain + for (const vaaId of vaaIds) { + const vaaBytes = await fetchVaa([vaaId]); - ??? child "Event Arguments" + console.log( + `Transaction: ${tx}\nVAA ID: ${vaaId}\nVAA Bytes: ${ + vaaBytes.length > 0 ? vaaBytes[0].vaaBytes : 'Not found' + }` + ); + } + } +}; - `nonce` ++"uint64"++ - - Unique nonce reserved by message (indexed). +testFetchVaa(); + ``` - --- + 3. **Run the script** - `burnToken` ++"address"++ - - Address of token burnt on source domain. + ```bash + npx tsx test/fetchVaa.run.ts + ``` - --- + If successful, the output will be: - `amount` ++"uint256"++ - - The deposit amount. +
+npx tsx test/fetchVaa.run.ts + +Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 +VAA Bytes: AQAAAAMNANQSwD/HRPcKp7Yxypl1ON8dZeMBzgYJrd2KYz6l9Tq9K9fj72fYJgkMeMaB9h... + +
- --- + If no VAA is found, the script will log an error message. - `depositor` ++"address"++ - - Address where deposit is transferred from. +### Validate VAA Signatures - --- +Now, we need to verify its validity. A VAA is only considered valid if it contains signatures from currently active Guardians and is correctly verified by the Wormhole Core contract. - `mintRecipient` ++"bytes32"++ - - Address receiving minted tokens on destination domain. +Open `src/helpers/vaaHelper.ts` and add the `checkVaaValidity()` function. This function verifies whether a VAA is valid by submitting it to an Ethereum RPC node and checking for outdated signatures. - --- +Follow these steps to implement the function: - `destinationDomain` ++"uint32"++ - - - Destination domain. +1. **Prepare the VAA for verification** - construct the VAA payload in a format that can be sent to the Wormhole Core contract - --- +2. **Send an `eth_call` request** - submit the VAA to an Ethereum RPC node, calling the `parseAndVerifyVM` function on the Wormhole Core contract - `destinationTokenMessenger` ++"bytes32"++ - - Address of `TokenMessenger` on destination domain. - - --- +3. **Decode the response** - check whether the VAA is valid. If it contains outdated signatures, further action will be required to replace them - `destinationCaller` ++"bytes32"++ - - Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. +```typescript title="src/helpers/vaaHelper.ts" +try { + const vaa = Buffer.from(vaaBytes, 'base64'); + vaa[4] = 4; // Set guardian set index to 4 -- **`depositForBurnWithCaller`** - deposits and burns tokens from the sender to be minted on the destination domain. This method differs from `depositForBurn` in that the mint on the destination domain can only be called by the designated `destinationCaller` address - - ??? interface "Parameters" + const result = ( + await axios.post(RPC, { + jsonrpc: '2.0', + id: 1, + method: 'eth_call', + params: [ + { + from: null, + to: ETH_CORE, + data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [ + `0x${vaa.toString('hex')}`, + ]), + }, + 'latest', + ], + }) + ).data.result; - `amount` ++"uint256"++ - - The amount of tokens to burn. + const decoded = eth.abi.decodeParameters( + PARSE_AND_VERIFY_VM_ABI.outputs, + result + ); + console.log( + `${decoded.valid ? '✅' : '❌'} VAA Valid: ${decoded.valid}${ + decoded.valid ? '' : `, Reason: ${decoded.reason}` + }` + ); - --- + return { valid: decoded.valid, reason: decoded.reason }; + } catch (error) { + console.error(`Error checking VAA validity:`, error); + return { valid: false, reason: 'RPC error' }; + } +} +``` - `destinationDomain` ++"uint32"++ - - The network where the token will be minted after burn. +???- code "Try it out: VAA Validity" + If you want to try the function before moving forward, create a script inside the `test` directory - --- + 1. **Create the script file** - `mintRecipient` ++"bytes32"++ - - Address of mint recipient on destination domain. + ```bash + touch test/checkVaaValidity.run.ts + ``` - --- + 2. **Add the function call** - `burnToken` ++"address"++ - - Address of contract to burn deposited tokens, on local domain. + ```typescript title="test/checkVaaValidity.run.ts" + import { + fetchVaaId, + fetchVaa, + checkVaaValidity, +} from '../src/helpers/vaaHelper'; +import { TXS } from '../src/config/constants'; - --- +const testCheckVaaValidity = async () => { + for (const tx of TXS) { + const vaaIds = await fetchVaaId([tx]); - `destinationCaller` ++"bytes32"++ - - Address of the caller on the destination domain who will trigger the mint. + if (vaaIds.length === 0) { + console.log(`No VAA ID found for transaction: ${tx}`); + continue; + } - ??? interface "Returns" + for (const vaaId of vaaIds) { + const vaaData = await fetchVaa([vaaId]); - `_nonce` ++"uint64"++ - - Unique nonce reserved by message. + if (vaaData.length === 0 || !vaaData[0].vaaBytes) { + console.log(`VAA not found for ID: ${vaaId}`); + continue; + } - ??? interface "Emits" + const result = await checkVaaValidity(vaaData[0].vaaBytes); + console.log( + `Transaction: ${tx}\nVAA ID: ${vaaId}\nVAA Validity:`, + result + ); + } + } +}; - `DepositForBurn` - event emitted when `depositForBurnWithCaller` is called +testCheckVaaValidity(); + ``` - ??? child "Event Arguments" + 3. **Run the script** - `nonce` ++"uint64"++ - - Unique nonce reserved by message (indexed). + ```bash + npx tsx test/checkVaaValidity.run.ts + ``` - --- + If the VAA is valid, the output will be: - `burnToken` ++"address"++ - - Address of token burnt on source domain. +
+npx tsx test/checkVaaValidity.run.ts + +✅ VAA Valid: true + +
- --- + If invalid, the output will include the reason: - `amount` ++"uint256"++ - - The deposit amount. +
+npx tsx test/checkVaaValidity.run.ts + +❌ VAA Valid: false, Reason: VM signature invalid +Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 + +
- --- +### Fetch Observations (VAA Signatures) - `depositor` ++"address"++ - - Address where deposit is transferred from. +Before replacing outdated signatures, we need to fetch the original VAA signatures from Wormholescan. This allows us to compare them with the latest Guardian set and determine which ones need updating. - --- +Inside `src/helpers/vaaHelper.ts`, create the `fetchObservations()` function to query the Wormholescan API for observations related to a given VAA. Format the response by converting Guardian addresses to lowercase for consistency, and return an empty array if an error occurs. - `mintRecipient` ++"bytes32"++ - - Address receiving minted tokens on destination domain. +```typescript title="src/helpers/vaaHelper.ts" +try { + console.log(`Fetching observations`); - --- + const response = await axios.get( + `https://api.wormholescan.io/api/v1/observations/${vaaId}` + ); - `destinationDomain` ++"uint32"++ - - - Destination domain. + return response.data.map((obs: any) => ({ + guardianAddr: obs.guardianAddr.toLowerCase(), + signature: obs.signature, + })); + } catch (error) { + console.error(`Error fetching observations:`, error); + return []; + } +} +``` - --- +???- code "Try it out: Fetch Observations" + If you want to try the function before moving forward, create a script inside the `test` directory - `destinationTokenMessenger` ++"bytes32"++ - - Address of `TokenMessenger` on destination domain. - - --- + 1. **Create the script file** - `destinationCaller` ++"bytes32"++ - - Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. + ```bash + touch test/fetchObservations.run.ts + ``` -- **`replaceDepositForBurn`** — replaces a previous `BurnMessage` to modify the mint recipient and/or the destination caller. The replacement message reuses the `_nonce` created by the original message, which allows the original message's sender to update the details without requiring a new deposit + 2. **Add the function call** - ??? interface "Parameters" + ```typescript title="test/fetchObservations.run.ts" + import { fetchVaaId, fetchObservations } from '../src/helpers/vaaHelper'; +import { TXS } from '../src/config/constants'; - `originalMessage` ++"bytes"++ - - The original burn message to be replaced. +const testFetchObservations = async () => { + for (const tx of TXS) { + const vaaIds = await fetchVaaId([tx]); - --- + if (vaaIds.length === 0) { + console.log(`No VAA ID found for transaction: ${tx}`); + continue; + } - `originalAttestation` ++"bytes"++ - - The attestation of the original message. + for (const vaaId of vaaIds) { + const observations = await fetchObservations(vaaId); - --- + if (observations.length === 0) { + console.log(`No observations found for VAA ID: ${vaaId}`); + continue; + } - `newDestinationCaller` ++"bytes32"++ - - The new caller on the destination domain, can be the same or updated. + console.log( + `Transaction: ${tx}\nVAA ID: ${vaaId}\nObservations:`, + observations + ); + } + } +}; - --- +testFetchObservations(); + ``` - `newMintRecipient` ++"bytes32"++ - - The new recipient for the minted tokens, can be the same or updated. + 3. **Run the script** - ??? interface "Returns" + ```bash + npx tsx test/fetchObservations.run.ts + ``` - None. + If successful, the output will be: - ??? interface "Emits" +
+npx tsx test/fetchObservations.run.ts + +Fetching observations +Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 +Observations: [ { guardianAddr: '0xda798f6896a3331f64b48c12d1d57fd9cbe70811', signature: + 'ZGFlMDYyOGNjZjFjMmE0ZTk5YzE2OThhZjAzMDM4NzZlYTM1OWMxMzczNDA3YzdlMDMxZTkyNzk0ODkwYjRiYjRiOWFmNzM3NjRiMzIyOTE0ZTQwYzNlMjllMWEzNmM2NTc3ZDc5ZTdhNTM2MzA5YjA4YjExZjE3YzE3MDViNWIwMQ==' + }, { guardianAddr: '0x74a3bf913953d695260d88bc1aa25a4eee363ef0', signature: + 'MzAyOTU4OGU4MWU0ODc0OTAwNDU3N2EzMGZlM2UxMDJjOWYwMjM0NWVhY2VmZWQ0ZGJlNTFkNmI3YzRhZmQ5ZTNiODFjNTg3MDNmYzUzNmJiYWFiZjNlODc1YTY3OTQwMGE4MmE3ZjZhNGYzOGY3YmRmNDNhM2VhNGQyNWNlNGMwMA==' + }, +...] + +
- `DepositForBurn` - event emitted when `replaceDepositForBurn` is called. Note that the `destinationCaller` will reflect the new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (`bytes32(0)`), indicating that any destination caller is valid + If no observations are found, the script will log an error message. - ??? child "Event Arguments" +### Fetch the Latest Guardian Set - `nonce` ++"uint64"++ - - Unique nonce reserved by message (indexed). +Now that we have the original VAA signatures, we must fetch the latest Guardian set from Wormholescan. This will allow us to compare the stored signatures with the current Guardians and determine which signatures need replacing. - --- +Create the `fetchGuardianSet()` function inside `src/helpers/vaaHelper.ts` to fetch the latest Guardian set. - `burnToken` ++"address"++ - - Address of token burnt on source domain. +```typescript title="src/helpers/vaaHelper.ts" +export async function fetchGuardianSet() { + try { + console.log('Fetching current guardian set'); - --- + const response = await axios.get(`${WORMHOLESCAN_API}/guardianset/current`); + const guardians = response.data.guardianSet.addresses.map((addr: string) => + addr.toLowerCase() + ); + const guardianSet = response.data.guardianSet.index; - `amount` ++"uint256"++ - - The deposit amount. + return [guardians, guardianSet]; + } catch (error) { + console.error('Error fetching guardian set:', error); + return []; + } +} +``` - --- +???- code "Try it out: Fetch Guardian Set" + If you want to try the function before moving forward, create a script inside the `test` directory - `depositor` ++"address"++ - - Address where deposit is transferred from. + 1. **Create the script file** - --- + ```bash + touch test/fetchGuardianSet.run.ts + ``` - `mintRecipient` ++"bytes32"++ - - Address receiving minted tokens on destination domain. + 2. **Add the function call** - --- + ```typescript title="test/fetchGuardianSet.run.ts" + import { fetchGuardianSet } from '../src/helpers/vaaHelper'; - `destinationDomain` ++"uint32"++ - - - Destination domain. +const testFetchGuardianSet = async () => { + const [guardians, guardianSetIndex] = await fetchGuardianSet(); - --- + console.log('Current Guardian Set Index:', guardianSetIndex); + console.log('Guardian Addresses:', guardians); +}; - `destinationTokenMessenger` ++"bytes32"++ - - Address of `TokenMessenger` on destination domain. - - --- +testFetchGuardianSet(); + ``` - `destinationCaller` ++"bytes32"++ - - Authorized caller of the `receiveMessage` function on the destination domain, if not equal to `bytes32(0)`. If equal to `bytes32(0)`, any address can call `receiveMessage`. + 3. **Run the script** -- **`handleReceiveMessage`** - handles an incoming message received by the local `MessageTransmitter` and takes the appropriate action. For a burn message, it mints the associated token to the requested recipient on the local domain. + ```bash + npx tsx test/fetchGuardianSet.run.ts + ``` - ???+ note + If successful, the output will be: - Though this function can only be called by the local `MessageTransmitter`, it is included here as it emits the essential event for minting tokens and withdrawing to send to the recipient. +
+npx tsx test/fetchGuardianSet.run.ts + +Fetching current guardian set +Current Guardian Set Index: 4 +Guardian Addresses: [ + '0x5893b5a76c3f739645648885bdccc06cd70a3cd3', + '0xff6cb952589bde862c25ef4392132fb9d4a42157', + '0x114de8460193bdf3a2fcf81f86a09765f4762fd1', + '0x107a0086b32d7a0977926a205131d8731d39cbeb', + +...] + +
- ??? interface "Parameters" + If an error occurs while fetching the Guardian set, a `500` status error will be logged. - `remoteDomain` ++"uint32"++ - - The domain where the message originated. +### Replace Outdated Signatures - --- +With the full VAA, Guardian signatures, and the latest Guardian set, we can now update outdated signatures while maintaining the required signature count. - `sender` ++"bytes32"++ - - The address of the sender of the message. +1. **Create the `replaceSignatures()` function** - open `src/helpers/vaaHelper.ts` and add the function header. To catch and handle errors properly, all logic will be wrapped inside a `try` block - --- + ```typescript title="src/helpers/vaaHelper.ts" + vaa: string | Uint8Array, + observations: { guardianAddr: string; signature: string }[], + currentGuardians: string[], + guardianSetIndex: number +) { + console.log('Replacing Signatures...'); - `messageBody` ++"bytes"++ - - The bytes making up the body of the message. + try { + // Add logic in the following steps here + console.error('Unexpected error in replaceSignatures:', error); + } +} + ``` - ??? interface "Returns" + - **`vaa`** - original VAA bytes + - **`observations`** - observed signatures from the network + - **`currentGuardians`** - latest Guardian set + - **`guardianSetIndex`** - current Guardian set index - `success` ++"boolean"++ - - Returns `true` if successful, otherwise, it returns `false`. +2. **Validate input data** - ensure all required parameters are present before proceeding. If any required input is missing, the function throws an error to prevent execution with incomplete data. The Guardian set should never be empty; if it is, this likely indicates an error in fetching the Guardian set in a previous step - ??? interface "Emits" + ```typescript + if (currentGuardians.length === 0) + throw new Error('Guardian set is empty.'); + if (observations.length === 0) throw new Error('No observations provided.'); + ``` - `MintAndWithdraw` - event emitted when tokens are minted +3. **Filter valid signatures** - remove signatures from inactive Guardians, keeping only valid ones. If there aren't enough valid signatures to replace the outdated ones, execution is halted to prevent an incomplete or invalid VAA - ??? child "Event arguments" + ```typescript + currentGuardians.includes(sig.guardianAddr) + ); - `localMinter` ++"address"++ - - Minter responsible for minting and burning tokens on the local domain. + if (validSigs.length === 0) + throw new Error('No valid signatures found. Cannot proceed.'); + ``` - --- +4. **Convert valid signatures** - ensure signatures are correctly formatted for verification. Convert hex-encoded signatures if necessary and extract their components - `remoteDomain` ++"uint32"++ - - The domain where the message originated from. + ```typescript + .map((sig) => { + try { + const sigBuffer = Buffer.from(sig.signature, 'base64'); + // If it's 130 bytes, it's hex-encoded and needs conversion + const sigBuffer1 = + sigBuffer.length === 130 + ? Buffer.from(sigBuffer.toString(), 'hex') + : sigBuffer; - --- + const r = BigInt('0x' + sigBuffer1.subarray(0, 32).toString('hex')); + const s = BigInt('0x' + sigBuffer1.subarray(32, 64).toString('hex')); + const vRaw = sigBuffer1[64]; + const v = vRaw < 27 ? vRaw : vRaw - 27; - `burnToken` ++"address"++ - - Address of contract to burn deposited tokens, on local domain. + return { + guardianIndex: currentGuardians.indexOf(sig.guardianAddr), + signature: new Signature(r, s, v), + }; + } catch (error) { + console.error( + `Failed to process signature for guardian: ${sig.guardianAddr}`, + error + ); + return null; + } + }) + .filter( + (sig): sig is { guardianIndex: number; signature: Signature } => + sig !== null + ); // Remove null values + ``` - --- +5. **Deserialize the VAA** - convert the raw VAA data into a structured format for further processing - `mintRecipient` ++"address"++ - - Recipient address of minted tokens (indexed). + ```typescript + try { + parsedVaa = deserialize('Uint8Array', vaa); + } catch (error) { + throw new Error(`Error deserializing VAA: ${error}`); + } + ``` - --- +6. **Identify outdated signatures** - compare the current VAA signatures with the newly formatted ones to detect which signatures belong to outdated Guardians. Remove these outdated signatures to ensure only valid ones remain - `amount` ++"uint256"++ - - Amount of minted tokens. + ```typescript + .filter( + (vaaSig) => + !formattedSigs.some( + (sig) => sig.guardianIndex === vaaSig.guardianIndex + ) + ) + .map((sig) => sig.guardianIndex); -### Message Transmitter Contract + console.log('Outdated Guardian Indexes:', outdatedGuardianIndexes); -The Message Transmitter contract ensures secure messaging across blockchain domains by managing message dispatch and tracking communication with events like `MessageSent` and `MessageReceived`. It uses a unique nonce for each message, which ensures proper validation, verifies attestation signatures, and prevents replay attacks. + let updatedSignatures = parsedVaa.signatures.filter( + (sig) => !outdatedGuardianIndexes.includes(sig.guardianIndex) + ); + ``` -The contract supports flexible delivery options, allowing messages to be sent to a specific `destinationCaller` or broadcast more generally. It also includes domain-specific configurations to manage communication between chains. +7. **Replace outdated signatures** - substitute outdated signatures with valid ones while maintaining the correct number of signatures. If there aren’t enough valid replacements, execution stops -Additional features include replacing previously sent messages, setting maximum message body sizes, and verifying that messages are received only once per nonce to maintain network integrity. + ```typescript + (sig) => + !updatedSignatures.some((s) => s.guardianIndex === sig.guardianIndex) + ); -??? code "Message Transmitter contract" - ```solidity - /* - * Copyright (c) 2022, Circle Internet Financial Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -pragma solidity 0.7.6; + // Check if we have enough valid signatures to replace outdated ones** + if (outdatedGuardianIndexes.length > validReplacements.length) { + console.warn( + `Not enough valid replacement signatures! Need ${outdatedGuardianIndexes.length}, but only ${validReplacements.length} available.` + ); + return; + } -import "@memview-sol/contracts/TypedMemView.sol"; -import "./interfaces/IMessageTransmitter.sol"; -import "./interfaces/IMessageHandler.sol"; -import "./messages/Message.sol"; -import "./roles/Pausable.sol"; -import "./roles/Rescuable.sol"; -import "./roles/Attestable.sol"; + updatedSignatures = [ + ...updatedSignatures, + ...validReplacements.slice(0, outdatedGuardianIndexes.length), + ]; -/** - * @title MessageTransmitter - * @notice Contract responsible for sending and receiving messages across chains. - */ -contract MessageTransmitter is - IMessageTransmitter, - Pausable, - Rescuable, - Attestable -{ - // ============ Events ============ - /** - * @notice Emitted when a new message is dispatched - * @param message Raw bytes of message - */ - event MessageSent(bytes message); + updatedSignatures.sort((a, b) => a.guardianIndex - b.guardianIndex); + ``` - /** - * @notice Emitted when a new message is received - * @param caller Caller (msg.sender) on destination domain - * @param sourceDomain The source domain this message originated from - * @param nonce The nonce unique to this message - * @param sender The sender of this message - * @param messageBody message body bytes - */ - event MessageReceived( - address indexed caller, - uint32 sourceDomain, - uint64 indexed nonce, - bytes32 sender, - bytes messageBody - ); +8. **Serialize the updated VAA** - reconstruct the VAA with the updated signatures and convert it into a format suitable for submission - /** - * @notice Emitted when max message body size is updated - * @param newMaxMessageBodySize new maximum message body size, in bytes - */ - event MaxMessageBodySizeUpdated(uint256 newMaxMessageBodySize); + ```typescript + ...parsedVaa, + guardianSet: guardianSetIndex, + signatures: updatedSignatures, + }; - // ============ Libraries ============ - using TypedMemView for bytes; - using TypedMemView for bytes29; - using Message for bytes29; + let patchedVaa: Uint8Array; + try { + patchedVaa = serialize(updatedVaa); + } catch (error) { + throw new Error(`Error serializing updated VAA: ${error}`); + } + ``` - // ============ State Variables ============ - // Domain of chain on which the contract is deployed - uint32 public immutable localDomain; +9. **Send the updated VAA for verification and handle errors** - submit the updated VAA to an Ethereum RPC node for validation, ensuring it can be proposed for Guardian approval. If an error occurs during submission or signature replacement, log the issue and prevent further execution - // Message Format version - uint32 public immutable version; + ```typescript + if (!(patchedVaa instanceof Uint8Array)) + throw new Error('Patched VAA is not a Uint8Array!'); - // Maximum size of message body, in bytes. - // This value is set by owner. - uint256 public maxMessageBodySize; + const vaaHex = `0x${Buffer.from(patchedVaa).toString('hex')}`; - // Next available nonce from this source domain - uint64 public nextAvailableNonce; + console.log('Sending updated VAA to RPC...'); - // Maps a bytes32 hash of (sourceDomain, nonce) -> uint256 (0 if unused, 1 if used) - mapping(bytes32 => uint256) public usedNonces; + const result = await axios.post(RPC, { + jsonrpc: '2.0', + id: 1, + method: 'eth_call', + params: [ + { + from: null, + to: ETH_CORE, + data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [vaaHex]), + }, + 'latest', + ], + }); - // ============ Constructor ============ - constructor( - uint32 _localDomain, - address _attester, - uint32 _maxMessageBodySize, - uint32 _version - ) Attestable(_attester) { - localDomain = _localDomain; - maxMessageBodySize = _maxMessageBodySize; - version = _version; + const verificationResult = result.data.result; + console.log('Updated VAA (hex):', vaaHex); + return verificationResult; + } catch (error) { + throw new Error(`Error sending updated VAA to RPC: ${error}`); } + ``` - // ============ External Functions ============ - /** - * @notice Send the message to the destination domain and recipient - * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. - * @param destinationDomain Domain of destination chain - * @param recipient Address of message recipient on destination chain as bytes32 - * @param messageBody Raw bytes content of message - * @return nonce reserved by message - */ - function sendMessage( - uint32 destinationDomain, - bytes32 recipient, - bytes calldata messageBody - ) external override whenNotPaused returns (uint64) { - bytes32 _emptyDestinationCaller = bytes32(0); - uint64 _nonce = _reserveAndIncrementNonce(); - bytes32 _messageSender = Message.addressToBytes32(msg.sender); - - _sendMessage( - destinationDomain, - recipient, - _emptyDestinationCaller, - _messageSender, - _nonce, - messageBody - ); - - return _nonce; - } +???- code "Complete Function" + ```typescript + vaa: string | Uint8Array, + observations: { guardianAddr: string; signature: string }[], + currentGuardians: string[], + guardianSetIndex: number +) { + console.log('Replacing Signatures...'); - /** - * @notice Replace a message with a new message body and/or destination caller. - * @dev The `originalAttestation` must be a valid attestation of `originalMessage`. - * Reverts if msg.sender does not match sender of original message, or if the source domain of the original message - * does not match this MessageTransmitter's local domain. - * @param originalMessage original message to replace - * @param originalAttestation attestation of `originalMessage` - * @param newMessageBody new message body of replaced message - * @param newDestinationCaller the new destination caller, which may be the - * same as the original destination caller, a new destination caller, or an empty - * destination caller (bytes32(0), indicating that any destination caller is valid.) - */ - function replaceMessage( - bytes calldata originalMessage, - bytes calldata originalAttestation, - bytes calldata newMessageBody, - bytes32 newDestinationCaller - ) external override whenNotPaused { - // Validate each signature in the attestation - _verifyAttestationSignatures(originalMessage, originalAttestation); + try { + if (!vaa) throw new Error('VAA is undefined or empty.'); + if (currentGuardians.length === 0) + throw new Error('Guardian set is empty.'); + if (observations.length === 0) throw new Error('No observations provided.'); - bytes29 _originalMsg = originalMessage.ref(0); + const validSigs = observations.filter((sig) => + currentGuardians.includes(sig.guardianAddr) + ); - // Validate message format - _originalMsg._validateMessageFormat(); + if (validSigs.length === 0) + throw new Error('No valid signatures found. Cannot proceed.'); - // Validate message sender - bytes32 _sender = _originalMsg._sender(); - require( - msg.sender == Message.bytes32ToAddress(_sender), - "Sender not permitted to use nonce" - ); + const formattedSigs = validSigs + .map((sig) => { + try { + const sigBuffer = Buffer.from(sig.signature, 'base64'); + // If it's 130 bytes, it's hex-encoded and needs conversion + const sigBuffer1 = + sigBuffer.length === 130 + ? Buffer.from(sigBuffer.toString(), 'hex') + : sigBuffer; - // Validate source domain - uint32 _sourceDomain = _originalMsg._sourceDomain(); - require( - _sourceDomain == localDomain, - "Message not originally sent from this domain" - ); + const r = BigInt('0x' + sigBuffer1.subarray(0, 32).toString('hex')); + const s = BigInt('0x' + sigBuffer1.subarray(32, 64).toString('hex')); + const vRaw = sigBuffer1[64]; + const v = vRaw < 27 ? vRaw : vRaw - 27; - uint32 _destinationDomain = _originalMsg._destinationDomain(); - bytes32 _recipient = _originalMsg._recipient(); - uint64 _nonce = _originalMsg._nonce(); + return { + guardianIndex: currentGuardians.indexOf(sig.guardianAddr), + signature: new Signature(r, s, v), + }; + } catch (error) { + console.error( + `Failed to process signature for guardian: ${sig.guardianAddr}`, + error + ); + return null; + } + }) + .filter( + (sig): sig is { guardianIndex: number; signature: Signature } => + sig !== null + ); // Remove null values - _sendMessage( - _destinationDomain, - _recipient, - newDestinationCaller, - _sender, - _nonce, - newMessageBody - ); + let parsedVaa: VAA<'Uint8Array'>; + try { + parsedVaa = deserialize('Uint8Array', vaa); + } catch (error) { + throw new Error(`Error deserializing VAA: ${error}`); } - /** - * @notice Send the message to the destination domain and recipient, for a specified `destinationCaller` on the - * destination domain. - * @dev Increment nonce, format the message, and emit `MessageSent` event with message information. - * WARNING: if the `destinationCaller` does not represent a valid address, then it will not be possible - * to broadcast the message on the destination domain. This is an advanced feature, and the standard - * sendMessage() should be preferred for use cases where a specific destination caller is not required. - * @param destinationDomain Domain of destination chain - * @param recipient Address of message recipient on destination domain as bytes32 - * @param destinationCaller caller on the destination domain, as bytes32 - * @param messageBody Raw bytes content of message - * @return nonce reserved by message - */ - function sendMessageWithCaller( - uint32 destinationDomain, - bytes32 recipient, - bytes32 destinationCaller, - bytes calldata messageBody - ) external override whenNotPaused returns (uint64) { - require( - destinationCaller != bytes32(0), - "Destination caller must be nonzero" - ); + const outdatedGuardianIndexes = parsedVaa.signatures + .filter( + (vaaSig) => + !formattedSigs.some( + (sig) => sig.guardianIndex === vaaSig.guardianIndex + ) + ) + .map((sig) => sig.guardianIndex); - uint64 _nonce = _reserveAndIncrementNonce(); - bytes32 _messageSender = Message.addressToBytes32(msg.sender); + console.log('Outdated Guardian Indexes:', outdatedGuardianIndexes); - _sendMessage( - destinationDomain, - recipient, - destinationCaller, - _messageSender, - _nonce, - messageBody - ); - - return _nonce; - } - - /** - * @notice Receive a message. Messages with a given nonce - * can only be broadcast once for a (sourceDomain, destinationDomain) - * pair. The message body of a valid message is passed to the - * specified recipient for further processing. - * - * @dev Attestation format: - * A valid attestation is the concatenated 65-byte signature(s) of exactly - * `thresholdSignature` signatures, in increasing order of attester address. - * ***If the attester addresses recovered from signatures are not in - * increasing order, signature verification will fail.*** - * If incorrect number of signatures or duplicate signatures are supplied, - * signature verification will fail. - * - * Message format: - * Field Bytes Type Index - * version 4 uint32 0 - * sourceDomain 4 uint32 4 - * destinationDomain 4 uint32 8 - * nonce 8 uint64 12 - * sender 32 bytes32 20 - * recipient 32 bytes32 52 - * messageBody dynamic bytes 84 - * @param message Message bytes - * @param attestation Concatenated 65-byte signature(s) of `message`, in increasing order - * of the attester address recovered from signatures. - * @return success bool, true if successful - */ - function receiveMessage(bytes calldata message, bytes calldata attestation) - external - override - whenNotPaused - returns (bool success) - { - // Validate each signature in the attestation - _verifyAttestationSignatures(message, attestation); - - bytes29 _msg = message.ref(0); - - // Validate message format - _msg._validateMessageFormat(); - - // Validate domain - require( - _msg._destinationDomain() == localDomain, - "Invalid destination domain" - ); + let updatedSignatures = parsedVaa.signatures.filter( + (sig) => !outdatedGuardianIndexes.includes(sig.guardianIndex) + ); - // Validate destination caller - if (_msg._destinationCaller() != bytes32(0)) { - require( - _msg._destinationCaller() == - Message.addressToBytes32(msg.sender), - "Invalid caller for message" - ); - } + const validReplacements = formattedSigs.filter( + (sig) => + !updatedSignatures.some((s) => s.guardianIndex === sig.guardianIndex) + ); - // Validate version - require(_msg._version() == version, "Invalid message version"); + // Check if we have enough valid signatures to replace outdated ones** + if (outdatedGuardianIndexes.length > validReplacements.length) { + console.warn( + `Not enough valid replacement signatures! Need ${outdatedGuardianIndexes.length}, but only ${validReplacements.length} available.` + ); + return; + } - // Validate nonce is available - uint32 _sourceDomain = _msg._sourceDomain(); - uint64 _nonce = _msg._nonce(); - bytes32 _sourceAndNonce = _hashSourceAndNonce(_sourceDomain, _nonce); - require(usedNonces[_sourceAndNonce] == 0, "Nonce already used"); - // Mark nonce used - usedNonces[_sourceAndNonce] = 1; + updatedSignatures = [ + ...updatedSignatures, + ...validReplacements.slice(0, outdatedGuardianIndexes.length), + ]; - // Handle receive message - bytes32 _sender = _msg._sender(); - bytes memory _messageBody = _msg._messageBody().clone(); - require( - IMessageHandler(Message.bytes32ToAddress(_msg._recipient())) - .handleReceiveMessage(_sourceDomain, _sender, _messageBody), - "handleReceiveMessage() failed" - ); + updatedSignatures.sort((a, b) => a.guardianIndex - b.guardianIndex); - // Emit MessageReceived event - emit MessageReceived( - msg.sender, - _sourceDomain, - _nonce, - _sender, - _messageBody - ); - return true; - } + const updatedVaa: VAA<'Uint8Array'> = { + ...parsedVaa, + guardianSet: guardianSetIndex, + signatures: updatedSignatures, + }; - /** - * @notice Sets the max message body size - * @dev This value should not be reduced without good reason, - * to avoid impacting users who rely on large messages. - * @param newMaxMessageBodySize new max message body size, in bytes - */ - function setMaxMessageBodySize(uint256 newMaxMessageBodySize) - external - onlyOwner - { - maxMessageBodySize = newMaxMessageBodySize; - emit MaxMessageBodySizeUpdated(maxMessageBodySize); + let patchedVaa: Uint8Array; + try { + patchedVaa = serialize(updatedVaa); + } catch (error) { + throw new Error(`Error serializing updated VAA: ${error}`); } - // ============ Internal Utils ============ - /** - * @notice Send the message to the destination domain and recipient. If `_destinationCaller` is not equal to bytes32(0), - * the message can only be received on the destination chain when called by `_destinationCaller`. - * @dev Format the message and emit `MessageSent` event with message information. - * @param _destinationDomain Domain of destination chain - * @param _recipient Address of message recipient on destination domain as bytes32 - * @param _destinationCaller caller on the destination domain, as bytes32 - * @param _sender message sender, as bytes32 - * @param _nonce nonce reserved for message - * @param _messageBody Raw bytes content of message - */ - function _sendMessage( - uint32 _destinationDomain, - bytes32 _recipient, - bytes32 _destinationCaller, - bytes32 _sender, - uint64 _nonce, - bytes calldata _messageBody - ) internal { - // Validate message body length - require( - _messageBody.length <= maxMessageBodySize, - "Message body exceeds max size" - ); - - require(_recipient != bytes32(0), "Recipient must be nonzero"); + try { + if (!(patchedVaa instanceof Uint8Array)) + throw new Error('Patched VAA is not a Uint8Array!'); - // serialize message - bytes memory _message = Message._formatMessage( - version, - localDomain, - _destinationDomain, - _nonce, - _sender, - _recipient, - _destinationCaller, - _messageBody - ); + const vaaHex = `0x${Buffer.from(patchedVaa).toString('hex')}`; - // Emit MessageSent event - emit MessageSent(_message); - } + console.log('Sending updated VAA to RPC...'); - /** - * @notice hashes `_source` and `_nonce`. - * @param _source Domain of chain where the transfer originated - * @param _nonce The unique identifier for the message from source to - destination - * @return hash of source and nonce - */ - function _hashSourceAndNonce(uint32 _source, uint64 _nonce) - internal - pure - returns (bytes32) - { - return keccak256(abi.encodePacked(_source, _nonce)); - } + const result = await axios.post(RPC, { + jsonrpc: '2.0', + id: 1, + method: 'eth_call', + params: [ + { + from: null, + to: ETH_CORE, + data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [vaaHex]), + }, + 'latest', + ], + }); - /** - * Reserve and increment next available nonce - * @return nonce reserved - */ - function _reserveAndIncrementNonce() internal returns (uint64) { - uint64 _nonceReserved = nextAvailableNonce; - nextAvailableNonce = nextAvailableNonce + 1; - return _nonceReserved; + const verificationResult = result.data.result; + console.log('Updated VAA (hex):', vaaHex); + return verificationResult; + } catch (error) { + throw new Error(`Error sending updated VAA to RPC: ${error}`); } + } catch (error) { + console.error('Unexpected error in replaceSignatures:', error); + } } ``` - This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol){target=\_blank} on GitHub. +## Create Script to Replace Outdated VAA Signatures -The functions provided by the Message Transmitter contract are as follows: +Now that we have all the necessary helper functions, we will create a script to automate replacing outdated VAA signatures. This script will retrieve a transaction’s VAA sequentially, check its validity, fetch the latest Guardian set, and update its signatures. By the end, it will output a correctly signed VAA that can be proposed for Guardian approval. -- **`receiveMessage`** — processes and validates an incoming message and its attestation. If valid, it triggers further action based on the message body +1. **Open the file** - inside `src/scripts/replaceSignatures.ts`, import the required helper functions needed to process the VAAs - ??? interface "Parameters" + ```typescript title="src/scripts/replaceSignatures.ts" + fetchVaaId, + fetchVaa, + checkVaaValidity, + fetchObservations, + fetchGuardianSet, + replaceSignatures, +} from '../helpers/vaaHelper'; +import { TXS } from '../config/constants'; + ``` - `message` ++"bytes"++ - - The message to be processed, including details such as sender, recipient, and message body. +2. **Define the main execution function** - add the following function inside `src/scripts/replaceSignatures.ts` to process each transaction in `TXS`, going step by step through the signature replacement process - --- + ```typescript + try { + for (const tx of TXS) { + console.log(`\nProcessing TX: ${tx}\n`); - `attestation` ++"bytes"++ - - Concatenated 65-byte signature(s) that attest to the validity of the `message`. + // 1. Fetch Transaction VAA IDs: + const vaaIds = await fetchVaaId([tx]); + if (!vaaIds.length) continue; - ??? interface "Returns" + // 2. Fetch VAA Data: + const vaaData = await fetchVaa(vaaIds); + if (!vaaData.length) continue; - `success` ++"boolean"++ - - Returns `true` if successful, otherwise, returns `false`. + const vaaBytes = vaaData[0].vaaBytes; + if (!vaaBytes) continue; - ??? interface "Emits" + // 3. Check VAA Validity: + const { valid } = await checkVaaValidity(vaaBytes); + if (valid) continue; - `MessageReceived` - event emitted when a new message is received + // 4. Fetch Observations (VAA signatures): + const observations = await fetchObservations(vaaIds[0]); - ??? child "Event arguments" + // 5. Fetch Current Guardian Set: + const [currentGuardians, guardianSetIndex] = await fetchGuardianSet(); - `caller` ++"address"++ - - Caller on destination domain. + // 6. Replace Signatures: + const response = await replaceSignatures( + Buffer.from(vaaBytes, 'base64'), + observations, + currentGuardians, + guardianSetIndex + ); - --- + if (!response) continue; + } + } catch (error) { + console.error('❌ Error in execution:', error); + process.exit(1); + } +} + ``` - `sourceDomain` ++"uint32"++ - - The source domain this message originated from. +3. **Make the script executable** - ensure it runs when executed - --- + ```typescript + + ``` - `nonce` ++"uint64"++ - - Nonce unique to this message (indexed). + To run the script, use the following command: - --- + ```bash + npx tsx src/scripts/replaceSignatures.ts + ``` - `sender` ++"bytes32"++ - - Sender of this message. +
+npx tsx src/scripts/replaceSignatures.ts + +Processing TX: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 +❌ VAA Valid: false, Reason: VM signature invalid +Fetching observations +Fetching current guardian set +Replacing Signatures... +Outdated Guardian Indexes: [ 0 ] +Sending updated VAA to RPC... +Updated VAA (hex): 0x01000000040d010019447b72d51e33923a3d6b28496ccd3722d5f1e33e2... + +
- --- +The script logs each step, skipping valid VAAs, replacing outdated signatures for invalid VAAs, and logging any errors. It then completes with a valid VAA ready for submission. - `messageBody` ++"bytes"++ - - The body of the message. +## Resources -- **`sendMessage`** — sends a message to the destination domain and recipient. It increments the `nonce`, assigns a unique `nonce` to the message, and emits a `MessageSent` event +You can explore the complete project and find all necessary scripts and configurations in Wormhole's [demo GitHub repository](https://github.com/wormhole-foundation/demo-vaa-signature-replacement){target=\_blank}. - ??? interface "Parameters" +The demo repository includes a bonus script to check the VAA redemption status on Ethereum and Solana, allowing you to verify whether a transaction has already been redeemed on the destination chain. - `destinationDomain` ++"uint32"++ - - The target blockchain network where the message is to be sent. +## Conclusion - --- +You've successfully built a script to fetch, validate, and replace outdated signatures in VAAs using Wormholescan and the Wormhole SDK. - `recipient` ++"bytes32"++ - - The recipient's address on the destination domain. +It's important to note that this tutorial does not update VAAs in the Wormhole network. Before redeeming the VAA, you must propose it for Guardian approval to finalize the process. +--- END CONTENT --- - --- +Doc-Content: https://wormhole.com/docs/products/multigov/concepts/architecture/ +--- BEGIN CONTENT --- +--- +title: MultiGov Architecture +description: Discover MultiGov's hub-and-spoke architecture, enabling secure cross-chain governance with Wormhole’s interoperability and decentralized coordination. +categories: MultiGov +--- - `messageBody` ++"bytes"++ - - The raw bytes content of the message. +# MultiGov Architecture - ??? interface "Returns" +MultiGov uses a hub-and-spoke architecture to coordinate governance across multiple blockchains. The hub chain is the central controller that handles proposal creation, vote aggregation, and execution. Spoke chains allow token holders to vote locally and can also execute proposal outcomes specific to their network. - `nonce` ++"uint64"++ - - Nonce unique to this message. +Wormhole’s multichain messaging infrastructure connects the hub and spokes, enabling secure and efficient chain communication. This design allows DAOs to operate seamlessly across ecosystems while maintaining a unified governance process. - ??? interface "Emits" +The diagram below illustrates this high-level architecture. - `MessageSent` - event emitted when a new message is dispatched +![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/products/multigov/concepts/architecture/architecture-1.webp) -??? child "Event arguments" +## Key Components - `message` ++"bytes"++ - - The raw bytes of the message. +### Hub Chain Contracts -- **`sendMessageWithCaller`** — sends a message to the destination domain and recipient, requiring a specific caller to trigger the message on the target chain. It increments the `nonce`, assigns a unique `nonce` to the message, and emits a `MessageSent` event +The hub chain is the central point for managing proposals, tallying votes, executing decisions, and coordinating governance across connected chains. - ??? interface "Parameters" + - **`HubGovernor`** - central governance contract managing proposals and vote tallying + - **`HubVotePool`** - receives aggregated votes from spokes and submits them to `HubGovernor` + - **`HubMessageDispatcher`** - relays approved proposal executions to spoke chains + - **`HubProposalExtender`** - allows trusted actors to extend voting periods if needed + - **`HubProposalMetadata`** - helper contract returning `proposalId` and vote start for `HubGovernor` proposals + - **`HubEvmSpokeAggregateProposer`** - aggregates cross-chain voting weight for an address and proposes via the `HubGovernor` if eligible - `destinationDomain` ++"uint32"++ - - The target blockchain network where the message is to be sent. +### Spoke Chains Contracts - --- +Spoke chains handle local voting, forward votes to the hub, and execute approved proposals from the hub for decentralized governance. - `recipient` ++"bytes32"++ - - The recipient's address on the destination domain. + - **`SpokeVoteAggregator`** - collects votes on the spoke chain and forwards them to the hub + - **`SpokeMessageExecutor`** - receives and executes approved proposals from the hub + - **`SpokeMetadataCollector`** - fetches proposal metadata from the hub for spoke chain voters + - **`SpokeAirlock`** - acts as governance's "admin" on the spoke, has permissions, and its treasury - --- +### Spoke Solana Staking Program - `destinationCaller` ++"bytes32"++ - - The caller on the destination domain. +The Spoke Solana Staking Program handles local voting from users who have staked W tokens or are vested in the program, forwards votes to the hub, and executes approved proposals from the hub for decentralized governance. - --- +The program implements its functionality through instructions, using specialized PDA accounts where data is stored. Below are the key accounts in the program: - `messageBody` ++"bytes"++ - - The raw bytes content of the message. + - **`GlobalConfig`** - global program configuration + - **`StakeAccountMetadata`** - stores user's staking information + - **`CustodyAuthority`** - PDA account managing custody and overseeing token operations related to stake accounts + - **`StakeAccountCustody`** - token account associated with a stake account for securely storing staked tokens + - **`CheckpointData`** - tracks delegation history + - **`SpokeMetadataCollector`** - collects and updates proposal metadata from the hub chain + - **`GuardianSignatures`** - stores guardian signatures for message verification + - **`ProposalData`** - stores data about a specific proposal, including votes and start time + - **`ProposalVotersWeightCast`** - tracks individual voter's weight for a proposal + - **`SpokeMessageExecutor`** - processes messages from a spoke chain via the Wormhole protocol + - **`SpokeAirlock`** - manages PDA signing and seed validation for secure instruction execution + - **`VestingBalance`** - stores total vesting balance and related staking information of a vester + - **`VestingConfig`** - defines vesting configuration, including mint and admin details + - **`Vesting`** - represents individual vesting allocations with maturation data + - **`VoteWeightWindowLengths`** - tracks lengths of vote weight windows - ??? interface "Returns" +Each account is implemented as a Solana PDA (Program Derived Address) and utilizes Anchor's account framework for serialization and management. - `nonce` ++"uint64"++ - - Nonce unique to this message. +## System Workflow - ??? interface "Emits" +The MultiGov system workflow details the step-by-step process for creating, voting on, and executing governance proposals across connected chains, from proposal creation to final cross-chain execution. - `MessageSent` - event emitted when a new message is dispatched +### EVM Governance Workflow -??? child "Event arguments" +The EVM-based MultiGov workflow follows these steps: - `message` ++"bytes"++ - - The raw bytes of the message. +1. **Proposal creation**: + 1. A user creates a proposal through the `HubEvmSpokeAggregateProposer`, which checks eligibility across chains, or directly on the `HubGovernor` via the `propose` method + 2. The proposal is submitted to the `HubGovernor` if the user meets the proposal threshold +2. **Proposal metadata distribution**: + 1. `HubProposalMetadata` creates a custom view method to be queried for use in the `SpokeMetadataCollector` + 2. `SpokeMetadataCollector` on each spoke chain queries `HubProposalMetadata` for proposal details +3. **Voting process**: + 1. Users on spoke chains vote through their respective `SpokeVoteAggregators` + 2. `SpokeVoteAggregators` send aggregated votes to the `HubVotePool` via Wormhole + 3. `HubVotePool` submits the aggregated votes to the `HubGovernor` +4. **Vote tallying and proposal execution**: + 1. `HubGovernor` tallies votes from all chains + 2. If a quorum is reached and there are more for votes than against votes, the vote passes and is queued for execution + 3. After the timelock delay, the proposal can be executed on the hub chain + 4. For cross-chain actions, a proposal should call the `dispatch` method in the `HubMessageDispatcher`, which sends execution messages to the relevant spoke chains + 5. `SpokeMessageExecutors` on each spoke chain receive and execute the approved actions through their respective `SpokeAirlocks` -- **`replaceMessage`** — replaces an original message with a new message body and/or updates the destination caller. The replacement message reuses the `_nonce` created by the original message +### Solana Governance Workflow - ??? interface "Parameters" +The Solana-based MultiGov workflow follows these steps: - `originalMessage` ++"bytes"++ - - The original message to be replaced. +1. **Proposal creation**: + 1. A user creates a proposal on `HubGovernor` by calling the `propose` method, provided they meet the proposal threshold + 2. For the proposal to be executed on the Solana blockchain, a `SolanaPayload` must be generated and included in the `calldata` parameter of the `propose` function + 3. The `SolanaPayload` contains encoded details specifying which instructions will be executed and which Solana program is responsible for execution - --- +2. **Proposal metadata distribution**: + 1. A user queries `getProposalMetadata` from `HubProposalMetadata` via the Wormhole query system to create a proposal on the **Spoke Solana Chain Staking Program** + 2. The retrieved metadata is used in the `AddProposal` instruction in the Solana program + 3. The proposal data is verified to ensure it matches the expected format + 4. Guardian signatures are posted using the `PostSignatures` instruction + 5. Once validated, the proposal is stored on-chain - `originalAttestation` ++"bytes"++ - - Attestation verifying the original message. +3. **Voting process**: + 1. Users vote on proposals stored in the `ProposalData` account on Solana + 2. The `CastVote` instruction records their choice (`for_votes`, `against_votes`, or `abstain_votes`) + 3. Eligibility and vote weight are verified using historical voter checkpoint data + 4. A **Query Wormhole** request retrieves vote data from a Solana PDA + 5. The signed response from Wormhole guardians is submitted to the `HubVotePool` on Ethereum for verification + 6. The `crossChainVote` function in `HubVotePool` processes the validated response and forwards the aggregated vote data to the `HubGovernor` to finalize the decision - --- +4. **Vote tallying and proposal execution**: + 1. `HubGovernor` tallies votes from all chains + 2. If a quorum is reached with more **for votes** than **against votes**, the proposal passes and is queued for execution + 3. After the timelock delay, the proposal can be executed either on the hub chain or another chain + 4. For cross-chain execution involving Solana, the proposal calls the `dispatch` method in `HubSolanaMessageDispatcher`, which sends execution messages to Solana + 5. On Solana, the `ReceiveMessage` instruction processes the approved message, and the `SpokeAirlock` executes the corresponding instructions - `newMessageBody` ++"bytes"++ - - The new content for the replaced message. +## Cross-Chain Communication - --- +MultiGov relies on Wormhole's infrastructure for all cross-chain messaging, ensuring secure and reliable communication between chains. Wormhole's cross-chain state read system, known as Queries, is used for vote aggregation and proposal metadata. Additionally, cross-chain proposal execution messages are transmitted through Wormhole's custom relaying system, enabling seamless coordination across multiple blockchain networks. - `newDestinationCaller` ++"bytes32"++ - - The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (`bytes32(0)`), indicating that any destination caller is valid. +## Security Measures - ??? interface "Returns" +- **Vote weight window** - implements a moving window for vote weight checkpoints to mitigate cross-chain double voting + - **Proposal extension** - `HubProposalExtender` allows for extending voting periods by a trusted actor in the case of network issues or high-stakes decisions +- **Timelock** - a timelock period between proposal approval and execution allows for additional security checks and community review +- **Wormhole verification** - all cross-chain messages are verified using Wormhole's secure messaging protocol - None. +## Detailed Architecture Diagram - ??? interface "Emits" +This architecture ensures that MultiGov can operate securely and efficiently across multiple chains, allowing for truly decentralized and cross-chain governance while maintaining a unified decision-making process. - `MessageSent` - event emitted when a new message is dispatched + +![detailed multigov architecture diagram](/docs/images/products/multigov/concepts/architecture/architecture-2.webp) +--- END CONTENT --- -??? child "Event arguments" +Doc-Content: https://wormhole.com/docs/products/multigov/faqs/ +--- BEGIN CONTENT --- +--- +title: MultiGov FAQs +description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. +categories: MultiGov +--- - `message` ++"bytes"++ - - The raw bytes of the message. +# FAQs -### Token Minter Contract +## What is MultiGov? -The Token Minter contract manages the minting and burning of tokens across different blockchain domains. It maintains a registry that links local tokens to their corresponding remote tokens, ensuring that tokens maintain a 1:1 exchange rate across domains. - -The contract restricts minting and burning functions to a designated Token Messenger, which ensures secure and reliable cross-chain operations. When tokens are burned on a remote domain, an equivalent amount is minted on the local domain for a specified recipient, and vice versa. +MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. It leverages Wormhole's interoperability infrastructure for seamless voting and proposal mechanisms across various chains. -To enhance control and flexibility, the contract includes mechanisms to pause operations, set burn limits, and update the Token Controller, which governs token minting permissions. Additionally, it provides functionality to add or remove the local Token Messenger and retrieve the local token address associated with a remote token. +## How does MultiGov ensure security in cross-chain communication? -??? code "Token Minter contract" - ```solidity - /* - * Copyright (c) 2022, Circle Internet Financial Limited. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -pragma solidity 0.7.6; +MultiGov leverages Wormhole's robust cross-chain communication protocol. It implements several security measures: -import "./interfaces/ITokenMinter.sol"; -import "./interfaces/IMintBurnToken.sol"; -import "./roles/Pausable.sol"; -import "./roles/Rescuable.sol"; -import "./roles/TokenController.sol"; -import "./TokenMessenger.sol"; +- Message origin verification to prevent unauthorized governance actions +- Timely and consistent data checks to ensure vote aggregation is based on recent and synchronized chain states +- Authorized participant validation to maintain the integrity of the governance process +- Replay attack prevention by tracking executed messages -/** - * @title TokenMinter - * @notice Token Minter and Burner - * @dev Maintains registry of local mintable tokens and corresponding tokens on remote domains. - * This registry can be used by caller to determine which token on local domain to mint for a - * burned token on a remote domain, and vice versa. - * It is assumed that local and remote tokens are fungible at a constant 1:1 exchange rate. - */ -contract TokenMinter is ITokenMinter, TokenController, Pausable, Rescuable { - // ============ Events ============ - /** - * @notice Emitted when a local TokenMessenger is added - * @param localTokenMessenger address of local TokenMessenger - * @notice Emitted when a local TokenMessenger is added - */ - event LocalTokenMessengerAdded(address localTokenMessenger); +## Can MultiGov integrate with any blockchain? - /** - * @notice Emitted when a local TokenMessenger is removed - * @param localTokenMessenger address of local TokenMessenger - * @notice Emitted when a local TokenMessenger is removed - */ - event LocalTokenMessengerRemoved(address localTokenMessenger); +MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/products/reference/supported-networks/#multigov). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. - // ============ State Variables ============ - // Local TokenMessenger with permission to call mint and burn on this TokenMinter - address public localTokenMessenger; +## How are votes aggregated across different chains? - // ============ Modifiers ============ - /** - * @notice Only accept messages from the registered message transmitter on local domain - */ - modifier onlyLocalTokenMessenger() { - require(_isLocalTokenMessenger(), "Caller not local TokenMessenger"); - _; - } +Votes are collected on each spoke chain using each chain's `SpokeVoteAggregator`. These votes are then transmitted to the HubVotePool on the hub chain for aggregation and tabulation. The `HubEvmSpokeVoteDecoder` standardizes votes from different EVM chains to ensure consistent processing. - // ============ Constructor ============ - /** - * @param _tokenController Token controller address - */ - constructor(address _tokenController) { - _setTokenController(_tokenController); - } +## Can governance upgrade from a single chain to MultiGov? - // ============ External Functions ============ - /** - * @notice Mints `amount` of local tokens corresponding to the - * given (`sourceDomain`, `burnToken`) pair, to `to` address. - * @dev reverts if the (`sourceDomain`, `burnToken`) pair does not - * map to a nonzero local token address. This mapping can be queried using - * getLocalToken(). - * @param sourceDomain Source domain where `burnToken` was burned. - * @param burnToken Burned token address as bytes32. - * @param to Address to receive minted tokens, corresponding to `burnToken`, - * on this domain. - * @param amount Amount of tokens to mint. Must be less than or equal - * to the minterAllowance of this TokenMinter for given `_mintToken`. - * @return mintToken token minted. - */ - function mint( - uint32 sourceDomain, - bytes32 burnToken, - address to, - uint256 amount - ) - external - override - whenNotPaused - onlyLocalTokenMessenger - returns (address mintToken) - { - address _mintToken = _getLocalToken(sourceDomain, burnToken); - require(_mintToken != address(0), "Mint token not supported"); - IMintBurnToken _token = IMintBurnToken(_mintToken); +Yes! MultiGov can support progressively upgrading from a single-chain governance to MultiGov. Moving to MultiGov requires upgrading the token to NTT and adding Flexible Voting to the original Governor. - require(_token.mint(to, amount), "Mint operation failed"); - return _mintToken; - } +## How can I create a proposal in MultiGov? - /** - * @notice Burn tokens owned by this TokenMinter. - * @param burnToken burnable token address. - * @param burnAmount amount of tokens to burn. Must be - * > 0, and <= maximum burn amount per message. - */ - function burn(address burnToken, uint256 burnAmount) - external - override - whenNotPaused - onlyLocalTokenMessenger - onlyWithinBurnLimit(burnToken, burnAmount) - { - IMintBurnToken _token = IMintBurnToken(burnToken); - _token.burn(burnAmount); - } +Proposals are created on the hub chain using the `HubEvmSpokeAggregateProposer` contract or by calling `propose` on the `HubGovernor`. You need to prepare the proposal details, including targets, values, and calldatas. The proposer's voting weight is aggregated across chains using Wormhole queries to determine eligibility. - /** - * @notice Add TokenMessenger for the local domain. Only this TokenMessenger - * has permission to call mint() and burn() on this TokenMinter. - * @dev Reverts if a TokenMessenger is already set for the local domain. - * @param newLocalTokenMessenger The address of the new TokenMessenger on the local domain. - */ - function addLocalTokenMessenger(address newLocalTokenMessenger) - external - onlyOwner - { - require( - newLocalTokenMessenger != address(0), - "Invalid TokenMessenger address" - ); +## How do I vote on a proposal if I hold tokens on a spoke chain? - require( - localTokenMessenger == address(0), - "Local TokenMessenger already set" - ); +You can vote on proposals via the `SpokeVoteAggregator` contract on the respective spoke chain where you hold your tokens. The votes are then automatically forwarded to the hub chain for aggregation. - localTokenMessenger = newLocalTokenMessenger; +## How are approved proposals executed across multiple chains? - emit LocalTokenMessengerAdded(localTokenMessenger); - } +When a proposal is approved and the timelock period elapses, it's first executed on the hub chain. A proposal can include a cross-chain message by including a call to `dispatch` on the `HubMessageDispatcher`, which sends a message to the relevant spoke chains. On each spoke chain, the `SpokeMessageExecutor` receives, verifies, and automatically executes the instructions using the `SpokeAirlock` as the `msg.sender`. - /** - * @notice Remove the TokenMessenger for the local domain. - * @dev Reverts if the TokenMessenger of the local domain is not set. - */ - function removeLocalTokenMessenger() external onlyOwner { - address _localTokenMessengerBeforeRemoval = localTokenMessenger; - require( - _localTokenMessengerBeforeRemoval != address(0), - "No local TokenMessenger is set" - ); +## What are the requirements for using MultiGov? - delete localTokenMessenger; - emit LocalTokenMessengerRemoved(_localTokenMessengerBeforeRemoval); - } +To use MultiGov, your DAO must meet the following requirements: - /** - * @notice Set tokenController to `newTokenController`, and - * emit `SetTokenController` event. - * @dev newTokenController must be nonzero. - * @param newTokenController address of new token controller - */ - function setTokenController(address newTokenController) - external - override - onlyOwner - { - _setTokenController(newTokenController); - } +- **ERC20Votes token** - your DAO's token must implement the `ERC20Votes` standard and support `CLOCK_MODE` timestamps for compatibility with cross-chain governance +- **Flexible voting support** - your DAO's Governor must support Flexible Voting to function as the Hub Governor. If your existing Governor does not support Flexible Voting, you can upgrade it to enable this feature - /** - * @notice Get the local token address associated with the given - * remote domain and token. - * @param remoteDomain Remote domain - * @param remoteToken Remote token - * @return local token address - */ - function getLocalToken(uint32 remoteDomain, bytes32 remoteToken) - external - view - override - returns (address) - { - return _getLocalToken(remoteDomain, remoteToken); - } +## What do I need to set up MultiGov for my project? - // ============ Internal Utils ============ - /** - * @notice Returns true if the message sender is the registered local TokenMessenger - * @return True if the message sender is the registered local TokenMessenger - */ - function _isLocalTokenMessenger() internal view returns (bool) { - return - address(localTokenMessenger) != address(0) && - msg.sender == address(localTokenMessenger); - } -} - ``` +Get started by filling out the form below: - This contract and the interfaces and contracts it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMinter.sol){target=\_blank} on GitHub. +https://www.tally.xyz/get-started -Most of the methods of the Token Minter contract can be called only by the registered Token Messenger. However, there is one publicly accessible method, a public view function that allows anyone to query the local token associated with a remote domain and token. +Tally will reach out to help get your DAO set up with MultiGov. -- **`getLocalToken`** — a read-only function that returns the local token address associated with a given remote domain and token +To set up testing MultiGov for your DAO, you'll need: - ??? interface "Parameters" +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} and [Git](https://git-scm.com/downloads){target=\_blank} installed +- Test ETH on the testnets you plan to use (e.g., Sepolia for hub, Optimism Sepolia for spoke) +- Modify and deploy the hub and spoke contracts using the provided scripts +- Set up the necessary environment variables and configurations - `remoteDomain` ++"uint32"++ - - The remote blockchain domain where the token resides. +## Can MultiGov be used with non-EVM chains? - --- +The current implementation is designed for EVM-compatible chains. However, Solana (non-EVM) voting is currently in development and expected to go live after the EVM contracts. - `remoteToken` ++"bytes32"++ - - The address of the token on the remote domain. +## How can I customize voting parameters in MultiGov? - ??? interface "Returns" +Voting parameters such as voting delay, voting period, proposal threshold, and quorum (and others) can be customized in the deployment scripts (`DeployHubContractsSepolia.s.sol` and `DeploySpokeContractsOptimismSepolia.s.sol` as examples for their respective chains). Make sure to adjust these parameters according to your DAO's specific needs before deployment. - ++"address"++ - - The local token address. +Remember to thoroughly test your MultiGov implementation on testnets before deploying to Mainnet, and have your contracts audited for additional security. -## How to Interact with CCTP Contracts +## How does MultiGov handle potential network issues or temporary chain unavailability? -Before writing your own contracts, it's essential to understand the key functions and events of the Wormhole CCTP contracts. The primary functionality revolves around the following: +MultiGov includes several mechanisms to handle network issues or temporary chain unavailability: -- **Sending tokens with a message payload** - initiating a cross-chain transfer of Circle-supported assets along with a message payload to a specific target address on the target chain -- **Receiving tokens with a message payload** - validating messages received from other chains via Wormhole and then minting the tokens for the recipient +1. **Asynchronous vote aggregation** - votes are aggregated periodically, allowing the system to continue functioning even if one chain is temporarily unavailable +2. **Proposal extension** - the `HubGovernorProposalExtender` allows trusted actors to extend voting periods if needed, which can help mitigate issues caused by temporary network problems +3. **Wormhole retry mechanism** - Wormhole's infrastructure includes retry mechanisms for failed message deliveries, helping ensure cross-chain messages eventually get through +4. **Decentralized relayer network** - Wormhole's decentralized network of relayers helps maintain system availability even if some relayers are offline -### Sending Tokens and Messages +However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. -To initiate a cross-chain transfer, you must call the `transferTokensWithPayload` method of Wormhole's Circle Integration (CCTP) contract. Once you have initiated a transfer, you must fetch the attested Wormhole message and parse the transaction logs to locate a transfer message emitted by the Circle Bridge contract. Then, a request must be sent to Circle's off-chain process with the transfer message to grab the attestation from the process's response, which validates the token mint on the target chain. +## How does MultiGov differ from traditional DAO governance? -To streamline this process, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/main){target=\_blank}, which exposes the [`WormholeRelayerSDK.sol` contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank}, including the [`CCTPSender` abstract contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase.sol){target=\_blank}. By inheriting this contract, you can transfer USDC while automatically relaying the message payload to the destination chain via a Wormhole-deployed relayer. +Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. -??? code "CCTP Sender contract" +## What are the main components of MultiGov? - ```solidity - abstract contract CCTPSender is CCTPBase { - uint8 internal constant CONSISTENCY_LEVEL_FINALIZED = 15; +The main components of MultiGov include: - using CCTPMessageLib for *; +- **Hub chain** - central coordination point for governance activities +- **Spoke chains** - additional chains where token holders can participate in governance +- **Wormhole integration** - enables secure cross-chain message passing +- **Governance token** - allows holders to participate in governance across all integrated chains +--- END CONTENT --- - mapping(uint16 => uint32) public chainIdToCCTPDomain; +Doc-Content: https://wormhole.com/docs/products/multigov/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with Multigov +description: Follow this guide to set up your environment and request access to deploy MultiGov contracts for multichain DAO governance using Wormhole messaging. +categories: MultiGov +--- - /** - * Sets the CCTP Domain corresponding to chain 'chain' to be 'cctpDomain' - * So that transfers of USDC to chain 'chain' use the target CCTP domain 'cctpDomain' - * - * This action can only be performed by 'cctpConfigurationOwner', who is set to be the deployer - * - * Currently, cctp domains are: - * Ethereum: Wormhole chain id 2, cctp domain 0 - * Avalanche: Wormhole chain id 6, cctp domain 1 - * Optimism: Wormhole chain id 24, cctp domain 2 - * Arbitrum: Wormhole chain id 23, cctp domain 3 - * Base: Wormhole chain id 30, cctp domain 6 - * - * These can be set via: - * setCCTPDomain(2, 0); - * setCCTPDomain(6, 1); - * setCCTPDomain(24, 2); - * setCCTPDomain(23, 3); - * setCCTPDomain(30, 6); - */ - function setCCTPDomain(uint16 chain, uint32 cctpDomain) public { - require( - msg.sender == cctpConfigurationOwner, - "Not allowed to set CCTP Domain" - ); - chainIdToCCTPDomain[chain] = cctpDomain; - } +# Get Started with Multigov - function getCCTPDomain(uint16 chain) internal view returns (uint32) { - return chainIdToCCTPDomain[chain]; - } +## Introduction - /** - * transferUSDC wraps common boilerplate for sending tokens to another chain using IWormholeRelayer - * - approves the Circle TokenMessenger contract to spend 'amount' of USDC - * - calls Circle's 'depositForBurnWithCaller' - * - returns key for inclusion in WormholeRelayer `additionalVaas` argument - * - * Note: this requires that only the targetAddress can redeem transfers. - * - */ +[MultiGov](/docs/products/multigov/overview/){target=\_blank} enables multichain governance using Wormhole messaging. With MultiGov, token holders can create proposals, vote, and execute decisions from any supported chain, eliminating the need to bridge assets or rely on a single governance hub. - function transferUSDC( - uint256 amount, - uint16 targetChain, - address targetAddress - ) internal returns (MessageKey memory) { - IERC20(USDC).approve(address(circleTokenMessenger), amount); - bytes32 targetAddressBytes32 = addressToBytes32CCTP(targetAddress); - uint64 nonce = circleTokenMessenger.depositForBurnWithCaller( - amount, - getCCTPDomain(targetChain), - targetAddressBytes32, - USDC, - targetAddressBytes32 - ); - return - MessageKey( - CCTPMessageLib.CCTP_KEY_TYPE, - abi.encodePacked(getCCTPDomain(wormhole.chainId()), nonce) - ); - } +This page walks you through the MultiGov deployment flow—from requesting access with Tally to choosing a network and following the appropriate deployment guide. - // Publishes a CCTP transfer of 'amount' of USDC - // and requests a delivery of the transfer along with 'payload' to 'targetAddress' on 'targetChain' - // - // The second step is done by publishing a wormhole message representing a request - // to call 'receiveWormholeMessages' on the address 'targetAddress' on chain 'targetChain' - // with the payload 'abi.encode(amount, payload)' - // (and we encode the amount so it can be checked on the target chain) - function sendUSDCWithPayloadToEvm( - uint16 targetChain, - address targetAddress, - bytes memory payload, - uint256 receiverValue, - uint256 gasLimit, - uint256 amount - ) internal returns (uint64 sequence) { - MessageKey[] memory messageKeys = new MessageKey[](1); - messageKeys[0] = transferUSDC(amount, targetChain, targetAddress); +## Prerequisites - bytes memory userPayload = abi.encode(amount, payload); - address defaultDeliveryProvider = wormholeRelayer - .getDefaultDeliveryProvider(); +Before deploying MultiGov, you need a governance token deployed on multiple chains (ERC-20 or SPL): - (uint256 cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - receiverValue, - gasLimit - ); +- **EVM chains**: + - Your token must implement the [`ERC20Votes`](https://docs.openzeppelin.com/contracts/4.x/governance#erc20votes){target=\_blank} standard + - It must support `CLOCK_MODE` timestamps for compatibility with cross-chain voting - sequence = wormholeRelayer.sendToEvm{value: cost}( - targetChain, - targetAddress, - userPayload, - receiverValue, - 0, - gasLimit, - targetChain, - address(0x0), - defaultDeliveryProvider, - messageKeys, - CONSISTENCY_LEVEL_FINALIZED - ); - } +- **Solana**: + - Use an SPL token + - Voting eligibility and weight are managed by the [MultiGov staking program](/docs/products/multigov/concepts/architecture/#spoke-solana-staking-program){target=\_blank} - function addressToBytes32CCTP(address addr) private pure returns (bytes32) { - return bytes32(uint256(uint160(addr))); - } -} - ``` +## Request Tally Access -The `CCTPSender` abstract contract exposes the `sendUSDCWithPayloadToEvm` function. This function publishes a CCTP transfer of the provided `amount` of USDC and requests that the transfer be delivered along with a `payload` to the specified `targetAddress` on the `targetChain`. +MultiGov integrations are coordinated through [Tally](https://www.tally.xyz/explore){target=\_blank}, a multichain governance platform that powers proposal creation, voting, and execution. -```solidity -function sendUSDCWithPayloadToEvm( - uint16 targetChain, - address targetAddress, - bytes memory payload, - uint256 receiverValue, - uint256 gasLimit, - uint256 amount -) internal returns (uint64 sequence) -``` +To get started, fill out the integration [intake form](https://www.tally.xyz/get-started){target=\_blank}. The Tally team will review your application and contact you to discuss deployment and setup requirements. -??? interface "Parameters" +Once approved, review the deployment flow below to understand the integration process. Then, follow the appropriate deployment guide to integrate MultiGov with your governance token on EVM chains, Solana, or other supported networks. - `targetChain` ++"uint16"++ +## Deployment Flow - The target chain for the transfer. +MultiGov deployments follow a similar structure on both EVM and Solana. This section provides a high-level overview of the end-to-end flow. Each step is explained in more detail in the platform-specific deployment guides linked [below](#next-steps). - --- +[timeline(wormhole-docs/.snippets/text/products/multigov/deployment-flow-timeline.json)] - `targetAddress` ++"address"++ +## Next Steps - The target address for the transfer. +You've now completed the initial setup and requested access through Tally. Continue to the deployment guide that matches your governance architecture: - --- + - [**Deploy on EVM Chains**](/docs/products/multigov/guides/deploy-to-evm){target=\_blank}: Configure and deploy MultiGov smart contracts to EVM-compatible chains. + - [**Deploy on Solana**](/docs/products/multigov/guides/deploy-to-solana){target=\_blank}: Launch the Solana staking program and configure spoke chain participation. +--- END CONTENT --- - `payload` ++"bytes"++ +Doc-Content: https://wormhole.com/docs/products/multigov/guides/deploy-to-evm/ +--- BEGIN CONTENT --- +--- +title: Deploy MultiGov on EVM Chains +description: Set up and deploy MultiGov to EVM locally with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. +categories: MultiGov +--- - Arbitrary payload to be delivered to the target chain via Wormhole. +# Deploy MultiGov on EVM Chains - --- +This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/products/multigov/get-started/){target=\_blank}. - `gasLimit` ++"uint256"++ +Once your project is approved through the intake process and you’ve collaborated with the Tally team to tailor MultiGov to your requirements, use this guide to configure, compile, and deploy the necessary smart contracts across your desired blockchain networks. This deployment will enable decentralized governance across your hub and spoke chains. - The gas limit with which to call `targetAddress`. +## Prerequisites - --- +To interact with MultiGov, you'll need the following: - `amount` ++"uint256"++ +- Install [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} +- Install [Git](https://git-scm.com/downloads){target=\_blank} +- Clone the repository: + ```bash + git clone https://github.com/wormhole-foundation/multigov + cd evm # for evm testing/deploying + ``` - The amount of USDC to transfer. +## Development Setup - --- +For developers looking to set up a local MultiGov environment: -??? interface "Returns" +1. Install dependencies: + ```bash + forge install + ``` - `sequence` ++"uint64"++ +2. Set up environment variables: + ```bash + cp .env.example .env + ``` - Sequence number of the published VAA containing the delivery instructions. + Edit `.env` with your specific [configuration](#configuration){target=\_blank} -When the `sendUSDCWithPayloadToEvm` function is called, the following series of actions are executed: +3. Compile contracts: + ```bash + forge build + ``` -1. **USDC transfer initiation**: +4. Deploy contracts (example for Sepolia testnet): - - The Circle Token Messenger contract is approved to spend the specified amount of USDC. - - The `depositForBurnWithCaller` function of the Token Messenger contract is invoked - - A key is returned, which is to be provided to the Wormhole relayer for message delivery + For hub chains: + ```bash + forge script script/DeployHubContractsSepolia.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast + ``` -2. **Message encoding** - the message `payload` is encoded for transmission via the Wormhole relayer. The encoded value also includes the `amount` so that it can be checked on the target chain -3. **Retrieving delivery provider** - the current default delivery provider's address is retrieved -4. **Cost calculation** - the transfer cost is calculated using the Wormhole relayer's `quoteEVMDeliveryPrice` function -5. **Message dispatch**: + For spoke chains (e.g., Optimism Sepolia): + ```bash + forge script script/DeploySpokeContractsOptimismSepolia.s.sol --rpc-url $OPTIMISM_SEPOLIA_RPC_URL --broadcast + ``` - - The `sendToEvm` function of the Wormhole relayer is called with the encoded payload, the delivery provider's address, and the arguments passed to `sendUSDCWithPayloadToEvm` - - The function must be called with `msg.value` set to the previously calculated cost (from step 4) - - This function publishes an instruction for the delivery provider to relay the payload and VAAs specified by the key (from step 1) to the target address on the target chain +## Configuration -A simple example implementation is as follows: +When deploying MultiGov, several key parameters need to be set. Here are the most important configuration points: -```solidity -function sendCrossChainDeposit( - uint16 targetChain, - address targetAddress, - address recipient, - uint256 amount, - uint256, - gasLimit -) public payable { - uint256 cost = quoteCrossChainDeposit(targetChain); - require( - msg.value == cost, - "msg.value must be quoteCrossChainDeposit(targetChain)" - ); +### Hub Governor Key Parameters - IERC20(USDC).transferFrom(msg.sender, address(this), amount); +- `initialVotingDelay` ++"uint256"++ - the delay measured in seconds before voting on a proposal begins. For example, `86400` is one day +- `initialProposalThreshold` ++"uint256"++ - the number of tokens needed to create a proposal +- `initialQuorum` ++"uint256"++ - the minimum number of votes needed for a proposal to be successful +- `initialVoteWeightWindow` ++"uint256"++ - a window where the minimum checkpointed voting weight is taken for a given address. The window ends at the vote start for a proposal and begins at the vote start minus the vote weight window. The voting window is measured in seconds, e.g., `86400` is one day - bytes memory payload = abi.encode(recipient); - sendUSDCWithPayloadToEvm( - targetChain, - targetAddress, // address (on targetChain) to send token and payload to - payload, - 0, // receiver value - gasLimit, - amount - ); -} -``` + !!! note + This helps mitigate cross-chain double voting. -The above example sends a specified amount of USDC and the recipient's address as a payload to a target contract on another chain, ensuring that the correct cost is provided for the cross-chain transfer. +### Hub Proposal Extender Key Parameters -### Receiving Tokens and Messages +- `extensionDuration` ++"uint256"++ - the amount of time, in seconds, for which target proposals will be extended. For example, `10800` is three hours +- `minimumExtensionDuration` ++"uint256"++ - lower time limit, in seconds, for extension duration. For example, `3600` is one hour -To complete the cross-chain transfer, you must invoke the `redeemTokensWithPayload` function on the target Wormhole Circle Integration contract. This function verifies the message's authenticity, decodes the payload, confirms the recipient and sender, checks message delivery, and then calls the `receiveMessage` function of the [Message Transmitter](#message-transmitter-contract) contract. +### Spoke Vote Aggregator Key Parameters -Using the Wormhole-deployed relayer automatically triggers the `receiveWormholeMessages` function. This function is defined in the [`WormholeRelayerSDK.sol` contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank} from the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/main){target=\_blank} and is implemented within the [`CCTPReceiver` abstract contract](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/CCTPBase.sol){target=\_blank}. +- `initialVoteWindow` ++"uint256"++ - the moving window in seconds for vote weight checkpoints. These checkpoints are taken whenever an address that is delegating sends or receives tokens. For example, `86400` is one day -??? code "CCTP Receiver contract" + !!! note + This is crucial for mitigating cross-chain double voting - ```solidity - abstract contract CCTPReceiver is CCTPBase { - function redeemUSDC( - bytes memory cctpMessage - ) internal returns (uint256 amount) { - (bytes memory message, bytes memory signature) = abi.decode( - cctpMessage, - (bytes, bytes) - ); - uint256 beforeBalance = IERC20(USDC).balanceOf(address(this)); - circleMessageTransmitter.receiveMessage(message, signature); - return IERC20(USDC).balanceOf(address(this)) - beforeBalance; - } +### Hub Evm Spoke Vote Aggregator Key Parameters - function receiveWormholeMessages( - bytes memory payload, - bytes[] memory additionalMessages, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 deliveryHash - ) external payable { - // Currently, 'sendUSDCWithPayloadToEVM' only sends one CCTP transfer - // That can be modified if the integrator desires to send multiple CCTP transfers - // in which case the following code would have to be modified to support - // redeeming these multiple transfers and checking that their 'amount's are accurate - require( - additionalMessages.length <= 1, - "CCTP: At most one Message is supported" - ); +- `maxQueryTimestampOffset` ++"uint256"++ - the max timestamp difference, in seconds, between the requested target time in the query and the current block time on the hub. For example, `1800` is 30 minutes - uint256 amountUSDCReceived; - if (additionalMessages.length == 1) - amountUSDCReceived = redeemUSDC(additionalMessages[0]); +### Updateable Governance Parameters - (uint256 amount, bytes memory userPayload) = abi.decode( - payload, - (uint256, bytes) - ); +The following key parameters can be updated through governance proposals: - // Check that the correct amount was received - // It is important to verify that the 'USDC' sent in by the relayer is the same amount - // that the sender sent in on the source chain - require(amount == amountUSDCReceived, "Wrong amount received"); +- `votingDelay` - delay before voting starts (in seconds) +- `votingPeriod` - duration of the voting period (in seconds) +- `proposalThreshold` - threshold for creating proposals (in tokens) +- `quorum` - number of votes required for quorum +- `extensionDuration` - the amount of time for which target proposals will be extended (in seconds) +- `voteWeightWindow` - window for vote weight checkpoints (in seconds) +- `maxQueryTimestampOffset` - max timestamp difference allowed between a query's target time and the hub's block time - receivePayloadAndUSDC( - userPayload, - amountUSDCReceived, - sourceAddress, - sourceChain, - deliveryHash - ); - } +These parameters can be queried using their respective getter functions on the applicable contract. - // Implement this function to handle in-bound deliveries that include a CCTP transfer - function receivePayloadAndUSDC( - bytes memory payload, - uint256 amountUSDCReceived, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 deliveryHash - ) internal virtual {} -} - ``` +To update these parameters, a governance proposal must be created, voted on, and executed through the standard MultiGov process. +--- END CONTENT --- -Although you do not need to interact with the `receiveWormholeMessages` function directly, it's important to understand what it does. This function processes cross-chain messages and USDC transfers via Wormhole's Circle (CCTP) Bridge. Here's a summary of what it does: +Doc-Content: https://wormhole.com/docs/products/multigov/guides/deploy-to-solana/ +--- BEGIN CONTENT --- +--- +title: MultiGov Deployment to Solana +description: Learn how to deploy the MultiGov Staking Program on Solana, including setup, funding, deployment, and configuration steps. +categories: MultiGov +--- -1. **Validate additional messages** - the function checks that there is at most one CCTP transfer message in the `additionalMessages` array, as it currently only supports processing a single CCTP transfer -2. **Redeem USDC**: - - If there is a CCTP message, it calls the `redeemUSDC` function of the `CCTPReceiver` contract to decode and redeem the USDC - - This results in the call of the `receiveMessage` function of Circle's Message Transmitter contract to redeem the USDC based on the provided message and signature - - The amount of USDC received is calculated by subtracting the contract's previous balance from the current balance after redeeming the USDC -3. **Decode payload** - the incoming payload is decoded, extracting both the expected amount of USDC and a `userPayload` (which could be any additional data) -4. **Verify the amount** - it ensures that the amount of USDC received matches the amount encoded in the payload. If the amounts don't match, the transaction is reverted -5. **Handle the payload and USDC** - after verifying the amounts, `receivePayloadAndUSDC` is called, which is meant to handle the actual logic for processing the received payload and USDC transfer +# Deploy MultiGov on Solana -You'll need to implement the `receivePayloadAndUSDC` function to transfer the USDC and handle the payload as your application needs. A simple example implementation is as follows: +This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/products/multigov/concepts/architecture/){target=\_blank}. -```solidity -function receivePayloadAndUSDC( - bytes memory payload, - uint256 amountUSDCReceived, - bytes32, // sourceAddress - uint16, // sourceChain - bytes32 // deliveryHash -) internal override onlyWormholeRelayer { - address recipient = abi.decode(payload, (address)); +Once your project setup is complete, follow this guide to configure, compile, and deploy the necessary Solana programs and supporting accounts. This deployment enables decentralized governance participation on Solana as a spoke chain within the MultiGov system. - IERC20(USDC).transfer(recipient, amountUSDCReceived); -} -``` +## Prerequisites -## Complete Example +To deploy MultiGov on Solana, ensure you have the following installed: -To view a complete example of creating a contract that integrates with Wormhole's CCTP contracts to send and receive USDC cross-chain, check out the [Hello USDC](https://github.com/wormhole-foundation/hello-usdc){target=\_blank} repository on GitHub. ---- END CONTENT --- + - Install [Git](https://git-scm.com/downloads){target=\_blank} + - Install [Node.js](https://nodejs.org/){target=\_blank} **`v20.10.0`** + - Install [Solana CLI](https://docs.anza.xyz/cli/install/){target=\_blank} **`v1.18.20`** + - Install [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`v0.30.1`** + - Install [Rust](https://www.rust-lang.org/tools/install){target=\_blank} **`v1.80.1`** + - Install [Docker](https://www.docker.com/get-started/){target=\_blank} + - Clone the repository: + ```bash + git clone https://github.com/wormhole-foundation/multigov.git + cd multigov/solana/ + ``` -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration-v0/ ---- BEGIN CONTENT --- ---- -title: Configure Your Connect Widget v0 -description: Configure Wormhole Connect v0 for React or HTML, set themes, define tokens, networks, and customize RPC endpoints for optimized blockchain interactions. ---- +## Build the Project -# Configure Your Connect Widget +To create a verifiable build of the MultiGov Staking Program, run the following command: -## Introduction {: #introduction } +```bash +./scripts/build_verifiable_staking_program.sh +``` -Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. +Once the build is complete, the compiled artifacts will be available in the `target` folder. -This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. +## Set Up the Deployer Account -!!! note - For documentation on the latest version of Connect, please refer to the current [configuration documentation](/docs/build/transfers/connect/configuration/){target=\_blank}. If you are looking to upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for detailed instructions. +For a successful deployment, you need a funded deployer account on Solana. This account will store the program and execute deployment transactions. -## Get Started +In this section, you will create a new keypair, check the account balance, and ensure it has enough SOL tokens to cover deployment costs. If needed, you can fund the account using different methods before deploying. -Configure the Wormhole Connect React component by passing a `WormholeConnectConfig` object as the `config` attribute. If using the hosted version, provide `config` and `theme` as JSON-serialized strings on the mount point. +### Generate a New Keypair -=== "React" +To create a new keypair and save it to a file, run the following command: - ```ts - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; - -const config: WormholeConnectConfig = { - networks: ['ethereum', 'polygon', 'solana'], - tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], - rpcs: { - ethereum: 'https://rpc.ankr.com/eth', - solana: 'https://rpc.ankr.com/solana', - } -} - - - ``` +```bash +solana-keygen new --outfile ./app/keypairs/deployer.json +``` -=== "HTML Tags" +### Check the Deployer Account Address - ```html -
- ``` +To retrieve the public address of the newly created keypair, run the following command: -## Examples {: #examples } +```bash +solana address -k ./app/keypairs/deployer.json +``` -Below are some examples of different ways you can configure Connect. See `WormholeConnectConfig` in the below file for a full view of the supported configuration parameters. +### Check the Deployer Account Balance -??? code "View `WormholeConnectConfig`" - ```ts - import { - ChainName, - WormholeContext, - WormholeConfig, - ChainResourceMap, -} from 'sdklegacy'; -import MAINNET from './mainnet'; -import TESTNET from './testnet'; -import DEVNET from './devnet'; -import type { WormholeConnectConfig } from './types'; -import { - Network, - InternalConfig, - Route, - WrappedTokenAddressCache, -} from './types'; -import { - mergeCustomTokensConfig, - mergeNttGroups, - validateDefaults, -} from './utils'; -import { wrapEventHandler } from './events'; +To verify the current balance of the deployer account, run the following command: -import { SDKConverter } from './converter'; +```bash +solana balance -k ./app/keypairs/deployer.json +``` -import { - wormhole as getWormholeV2, - Wormhole as WormholeV2, - Network as NetworkV2, - Token as TokenV2, - Chain as ChainV2, - ChainTokens as ChainTokensV2, - WormholeConfigOverrides as WormholeConfigOverridesV2, -} from '@wormhole-foundation/sdk'; +!!! warning + When deploying the MultiGov Staking Program, the deployer account must have enough SOL to cover deployment costs and transaction fees. -import '@wormhole-foundation/sdk/addresses'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import sui from '@wormhole-foundation/sdk/sui'; -import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; -import algorand from '@wormhole-foundation/sdk/algorand'; + - 7.60219224 SOL for deployment costs + - 0.00542 SOL for transaction fees -export function buildConfig( - customConfig?: WormholeConnectConfig -): InternalConfig { - const network = ( - customConfig?.network || - customConfig?.env || // TODO remove; deprecated - import.meta.env.REACT_APP_CONNECT_ENV?.toLowerCase() || - 'mainnet' - ).toLowerCase() as Network; +### Fund the Deployer Account - if (!['mainnet', 'testnet', 'devnet'].includes(network)) - throw new Error(`Invalid env "${network}"`); +If the account does not have enough SOL, use one of the following methods to add funds. - const networkData = { MAINNET, DEVNET, TESTNET }[network.toUpperCase()]!; + - **Transfer SOL from another account** - if you already have SOL in another account, transfer it using a wallet (Phantom, Solflare, etc.) or in the terminal - const tokens = mergeCustomTokensConfig( - networkData.tokens, - customConfig?.tokensConfig - ); + ```bash + solana transfer --from /path/to/funder.json + ``` - const sdkConfig = WormholeContext.getConfig(network); + - **Request an airdrop (devnet only)** - if deploying to devnet, you can request free SOL - const rpcs = Object.assign( - {}, - sdkConfig.rpcs, - networkData.rpcs, - customConfig?.rpcs - ); + ```bash + solana airdrop 2 -k ./app/keypairs/deployer.json + ``` - const wh = getWormholeContext(network, sdkConfig, rpcs); + - **Use a Solana faucet (devnet only)** - you can use online faucets to receive 10 free SOL - if (customConfig?.bridgeDefaults) { - validateDefaults(customConfig.bridgeDefaults, networkData.chains, tokens); - } + - [Solana Faucet](https://faucet.solana.com/){target=\_blank} - const sdkConverter = new SDKConverter(wh); +## Deploy the MultiGov Staking Program - return { - wh, - sdkConfig, - sdkConverter, +With the deployer account set up and funded, you can deploy the MultiGov Staking Program to the Solana blockchain. This step involves deploying the program, verifying the deployment, and ensuring the necessary storage and metadata are correctly configured. Once the IDL is initialized, the program will be ready for further setup and interaction. - v2Network: sdkConverter.toNetworkV2(network), +### Deploy the Program - network, - isMainnet: network === 'mainnet', - // External resources - rpcs, - rest: Object.assign( - {}, - sdkConfig.rest, - networkData.rest, - customConfig?.rest - ), - graphql: Object.assign({}, networkData.graphql, customConfig?.graphql), - wormholeApi: { - mainnet: 'https://api.wormholescan.io/', - testnet: 'https://api.testnet.wormholescan.io/', - devnet: '', - }[network], - wormholeRpcHosts: { - mainnet: [ - 'https://wormhole-v2-mainnet-api.mcf.rocks', - 'https://wormhole-v2-mainnet-api.chainlayer.network', - 'https://wormhole-v2-mainnet-api.staking.fund', - ], - testnet: [ - 'https://guardian.testnet.xlabs.xyz', - 'https://guardian-01.testnet.xlabs.xyz', - 'https://guardian-02.testnet.xlabs.xyz', - ], - devnet: ['http://localhost:7071'], - }[network], - coinGeckoApiKey: customConfig?.coinGeckoApiKey, +Deploy the MultiGov Staking Program using Anchor: - // Callbacks - triggerEvent: wrapEventHandler(customConfig?.eventHandler), - validateTransfer: customConfig?.validateTransferHandler, +```bash +anchor deploy --provider.cluster https://api.devnet.solana.com --provider.wallet ./app/keypairs/deployer.json +``` - // White lists - chains: networkData.chains, - chainsArr: Object.values(networkData.chains).filter((chain) => { - return customConfig?.networks - ? customConfig.networks!.includes(chain.key) - : true; - }), - tokens, - tokensArr: Object.values(tokens).filter((token) => { - return customConfig?.tokens - ? customConfig.tokens!.includes(token.key) - : true; - }), +### Verify the Deployment - // For token bridge ^_^ - wrappedTokenAddressCache: new WrappedTokenAddressCache( - tokens, - sdkConverter - ), +After deployment, check if the program is successfully deployed by running the following command: - gasEstimates: networkData.gasEstimates, - // TODO: routes that aren't supported yet are disabled - routes: (customConfig?.routes ?? Object.values(Route)).filter((r) => - [ - Route.Bridge, - Route.Relay, - Route.NttManual, - Route.NttRelay, - Route.CCTPManual, - Route.CCTPRelay, - ].includes(r as Route) - ), +```bash +solana program show INSERT_PROGRAM_ID +``` - // UI details - cta: customConfig?.cta, - explorer: customConfig?.explorer, - attestUrl: { - mainnet: 'https://portalbridge.com/advanced-tools/#/register', - devnet: '', - testnet: - 'https://wormhole-foundation.github.io/example-token-bridge-ui/#/register', - }[network], - bridgeDefaults: customConfig?.bridgeDefaults, - cctpWarning: customConfig?.cctpWarning?.href || '', - pageHeader: customConfig?.pageHeader, - pageSubHeader: customConfig?.pageSubHeader, - menu: customConfig?.menu ?? [], - searchTx: customConfig?.searchTx, - moreTokens: customConfig?.moreTokens, - moreNetworks: customConfig?.moreNetworks, - partnerLogo: customConfig?.partnerLogo, - walletConnectProjectId: - customConfig?.walletConnectProjectId ?? - import.meta.env.REACT_APP_WALLET_CONNECT_PROJECT_ID, - showHamburgerMenu: customConfig?.showHamburgerMenu ?? false, - previewMode: !!customConfig?.previewMode, +### Extend Program Storage - // Route options - ethBridgeMaxAmount: customConfig?.ethBridgeMaxAmount ?? 5, - wstETHBridgeMaxAmount: customConfig?.wstETHBridgeMaxAmount ?? 5, +If the deployed program requires additional storage space for updates or functionality, extend the program storage using the following command: - // NTT config - nttGroups: mergeNttGroups( - tokens, - networkData.nttGroups, - customConfig?.nttGroups - ), +```bash +solana program extend INSERT_PROGRAM_ID 800000 +``` - // Guardian set - guardianSet: networkData.guardianSet, +### Initialize the IDL - // Render redesign views - useRedesign: customConfig?.useRedesign, - }; -} +To associate an IDL file with the deployed program, run the following command: -// Running buildConfig with no argument generates the default configuration -const config = buildConfig(); -export default config; +```bash +anchor idl init --provider.cluster https://api.devnet.solana.com --filepath ./target/idl/staking.json INSERT_PROGRAM_ID +``` -// TODO SDKV2: REMOVE -export function getWormholeContext( - network: Network, - sdkConfig: WormholeConfig, - rpcs: ChainResourceMap -): WormholeContext { - const wh: WormholeContext = new WormholeContext(network, { - ...sdkConfig, - ...{ rpcs }, - }); +## Configure the Staking Program - return wh; -} +The final step after deploying the MultiGov Staking Program is configuring it for proper operation. This includes running a series of deployment scripts to initialize key components and set important governance parameters. These steps ensure that staking, governance, and cross-chain communication function as expected. -export function getDefaultWormholeContext(network: Network): WormholeContext { - const sdkConfig = WormholeContext.getConfig(network); - const networkData = { mainnet: MAINNET, devnet: DEVNET, testnet: TESTNET }[ - network - ]!; +### Run Deployment Scripts - const rpcs = Object.assign({}, sdkConfig.rpcs, networkData.rpcs); +After deploying the program and initializing the IDL, execute the following scripts **in order** to set up the staking environment and necessary accounts. - return getWormholeContext(network, sdkConfig, rpcs); -} +1. Initialize the MultiGov Staking Program with default settings: -export async function getWormholeContextV2(): Promise> { - if (config.v2Wormhole) return config.v2Wormhole; - config.v2Wormhole = await newWormholeContextV2(); - return config.v2Wormhole; -} + ```bash + npx ts-node app/deploy/01_init_staking.ts + ``` -export async function newWormholeContextV2(): Promise> { - const v2Config: WormholeConfigOverridesV2 = { chains: {} }; +2. Create an Account Lookup Table (ALT) to optimize transaction processing: - for (const key in config.chains) { - const chainV1 = key as ChainName; - const chainConfigV1 = config.chains[chainV1]!; + ```bash + npx ts-node app/deploy/02_create_account_lookup_table.ts + ``` - const chainContextV1 = chainConfigV1.context; +3. Set up airlock accounts: - const chainV2 = config.sdkConverter.toChainV2( - chainV1 as ChainName - ) as ChainV2; + ```bash + npx ts-node app/deploy/03_create_airlock.ts + ``` - const rpc = config.rpcs[chainV1]; - const tokenMap: ChainTokensV2 = {}; +4. Deploy a metadata collector: - for (const token of config.tokensArr) { - const nativeChainV2 = config.sdkConverter.toChainV2(token.nativeChain); + ```bash + npx ts-node app/deploy/04_create_spoke_metadata_collector.ts + ``` - const tokenV2: Partial = { - key: token.key, - chain: chainV2, - symbol: token.symbol, - }; +5. Configure vote weight window lengths: - if (nativeChainV2 == chainV2) { - const decimals = - token.decimals[chainContextV1] ?? token.decimals.default; - if (!decimals) { - continue; - } else { - tokenV2.decimals = decimals; - } - const address = config.sdkConverter.getNativeTokenAddressV2(token); - if (!address) throw new Error('Token must have address'); - tokenV2.address = address; - } else { - tokenV2.original = nativeChainV2; - if (token.foreignAssets) { - const fa = token.foreignAssets[chainV1]!; + ```bash + npx ts-node app/deploy/05_initializeVoteWeightWindowLengths.ts + ``` - if (!fa) { - continue; - } else { - tokenV2.address = fa.address; - tokenV2.decimals = fa.decimals; - } - } else { - continue; - } - } +6. Deploy the message executor for handling governance messages: - tokenMap[token.key] = tokenV2 as TokenV2; - } + ```bash + npx ts-node app/deploy/06_create_message_executor.ts + ``` - v2Config.chains![chainV2] = { rpc, tokenMap }; - } +### Set MultiGov Staking Program Key Parameters - return await getWormholeV2( - config.v2Network, - [evm, solana, aptos, cosmwasm, sui, algorand], - v2Config - ); -} +When deploying MultiGov on Solana, several key parameters need to be set. Here are the most important configuration points: -// setConfig can be called afterwards to override the default config with integrator-provided config -export function setConfig(customConfig?: WormholeConnectConfig) { - const newConfig: InternalConfig = buildConfig(customConfig); + - `maxCheckpointsAccountLimit` ++"u64"++ - the maximum number of checkpoints an account can have. For example, `654998` is used in production, while `15` might be used for testing + - `hubChainId` `u16` - the chain ID of the hub network where proposals are primarily managed. For example, `10002` for Sepolia testnet + - `hubProposalMetadata` ++"[u8; 20]"++ - an array of bytes representing the address of the Hub Proposal Metadata contract on Ethereum. This is used to identify proposals from the hub + - `voteWeightWindowLength` ++"u64"++ - specifies the length of the checkpoint window in seconds in which the minimum voting weight is taken. The window ends at the vote start for a proposal and begins at the vote start minus the vote weight window. The vote weight window helps solve problems such as manipulating votes in a chain + - `votingTokenMint` ++"Pubkey"++ - the mint address of the token used for voting + - `governanceAuthority` ++"Pubkey"++ - the account's public key with the authority to govern the staking system. The `governanceAuthority` should not be the default Pubkey, as this would indicate an uninitialized or incorrectly configured setup + - `vestingAdmin` ++"Pubkey"++ - the account's public key for managing vesting operations. The `vestingAdmin` should not be the default Pubkey, as this would indicate an uninitialized or incorrectly configured setup + - `hubDispatcher` ++"Pubkey"++ - the Solana public key derived from an Ethereum address on the hub chain that dispatches messages to the spoke chains. This is crucial for ensuring that only authorized messages from the hub are executed on the spoke +--- END CONTENT --- - // We overwrite keys in the existing object so the references to the config - // imported elsewhere point to the new values - for (const key in newConfig) { - /* @ts-ignore */ - config[key] = newConfig[key]; - } -} +Doc-Content: https://wormhole.com/docs/products/multigov/guides/upgrade-evm/ +--- BEGIN CONTENT --- +--- +title: Upgrading MultiGov on EVM +description: Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. +categories: MultiGov +--- -// TODO: add config validation step to buildConfig -//validateConfigs(); - - ``` +# Upgrade MultiGov Contracts on EVM Chains -### Custom Networks and RPC Endpoints {: #custom-networks-and-rpc-endpoints } +MultiGov is designed to be flexible but stable. Due to the system's complexity and cross-chain nature, upgrades should be rare and carefully considered. When upgrades are necessary, they must be meticulously planned and executed to ensure system integrity and continuity. -Specify supported networks, tokens, and custom RPC endpoints. Your users may encounter rate limits using public RPC endpoints if you don't provide your own. +## Key Considerations for Upgrades -=== "Mainnet" +- **`HubGovernor`**: + - Not upgradeable. A new deployment requires redeploying several components of the MultiGov system. Refer to the [Process for Major System Upgrade](#process-for-major-system-upgrade) section for more details - ```js - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +- **`HubVotePool`**: + - Can be replaced by setting a new `HubVotePool` on the `HubGovernor` + - Requires re-registering all spokes on the new `HubVotePool` + - Must register the query type and implementation for vote decoding by calling `registerQueryType` on the new `HubVotePool` + - A new proposal would have to authorize the governor to use the newly created hub vote pool and will also handle registering the appropriate query decoders and registering the appropriate spoke `SpokeVoteAggregators` -const config: WormholeConnectConfig = { - env: 'mainnet', - networks: ['ethereum', 'polygon', 'solana'], - tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], - rpcs: { - ethereum: 'https://rpc.ankr.com/eth', - solana: 'https://rpc.ankr.com/solana', - }, -}; +- **`SpokeMessageExecutor`**: + - Upgradeable via [UUPS](https://www.rareskills.io/post/uups-proxy){target=\_blank} proxy pattern + - Stores critical parameters in `SpokeMessageExecutorStorage` -function App() { - return ; -} - ``` +- **`HubEvmSpokeAggregateProposer`**: + - Needs redeployment if `HubGovernor` changes + - Requires re-registering all spokes after redeployment -=== "Testnet" +- **`HubProposalMetadata`**: + - Needs redeployment if `HubGovernor` changes, as it references `HubGovernor` as a parameter - ```js - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +- **`SpokeMetadataCollector`**: + - Requires redeployment if the hub chain ID changes or if `HubProposalMetadata` changes -const config: WormholeConnectConfig = { - env: 'testnet', - networks: ['sepolia', 'arbitrum_sepolia', 'base_sepolia', 'fuji'], +## Process for Major System Upgrade - rpcs: { - fuji: 'https://rpc.ankr.com/avalanche_fuji', - base_sepolia: 'https://base-sepolia-rpc.publicnode.com', - }, -}; +1. **New `HubGovernor` deployment**: + - Deploy the new `HubGovernor` contract +1. **Component redeployment**: + - Redeploy `HubEvmSpokeAggregateProposer` with the new `HubGovernor` address + - Redeploy `HubProposalMetadata` referencing the new `HubGovernor` + - If hub chain ID changes, redeploy `SpokeMetadataCollector` on all spoke chains +1. **`HubVotePool` update**: + - Set the new `HubVotePool` on the new `HubGovernor` + - Register all spokes on the new `HubVotePool` + - Register the query type and implementation for vote decoding (`HubEvmSpokeVoteDecoder`) +1. **Spoke re-registration**: + - Re-register all spokes on the new `HubEvmSpokeAggregateProposer` +1. **Verification and testing**: + - Conduct thorough testing of the new system setup + - Verify all cross-chain interactions are functioning correctly +1. **System transition and deprecation**: + - Create a proposal to switch the timelock to the new governor + - Communicate clearly to the community what changes were made +1. **Monitoring**: + - Implement a transition period where the new system is closely monitored + - Address any issues that arise promptly -function App() { - return ; -} - ``` +## Important Considerations -!!! note - For a complete list of testnet chain names that can be manually added, see the [Testnet Chains List](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/fa4ba4bc349a7caada809f209090d79a3c5962fe/tokenRegistry/src/scripts/importConnect.ts#L44-L55){target=\_blank}. +- Always prioritize system stability, upgrades should only be performed when absolutely necessary +- Thoroughly audit all new contract implementations before proposing an upgrade +- Account for all affected components across all chains in the upgrade plan +- Provide comprehensive documentation for the community about the upgrade process and any changes in functionality +- Always test upgrades extensively on testnets before implementing in production +--- END CONTENT --- -### Fully Customized Theme {: #fully-customized-theme } +Doc-Content: https://wormhole.com/docs/products/multigov/guides/upgrade-solana/ +--- BEGIN CONTENT --- +--- +title: Upgrading MultiGov on Solana +description: Learn the process and key considerations for upgrading MultiGov on Solana, ensuring system integrity and careful planning across cross-chain components. +categories: MultiGov +--- -Wormhole Connect offers a high level of customizability that suits and integrates with your application's design, including various options for buttons, backgrounds, popovers, fonts, and more. The following example demonstrates a variety of appearance customizations. Remember, if you prefer a visual to aid in designing your widget, you can use the [no code style interface](https://connect-in-style.wormhole.com/){target=\_blank}. +# Upgrade MultiGov Contracts on Solana -```jsx -import WormholeConnect, { - WormholeConnectTheme, -} from '@wormhole-foundation/wormhole-connect'; -import red from '@mui/material/colors/red'; -import lightblue from '@mui/material/colors/lightBlue'; -import grey from '@mui/material/colors/grey'; -import green from '@mui/material/colors/green'; -import orange from '@mui/material/colors/orange'; +The MultiGov Staking Program on Solana is designed to be upgradeable while maintaining stability. Upgrades introduce improvements, bug fixes, and new features but must be carefully planned and executed to prevent disruptions. -const customTheme: WormholeConnectTheme = { - mode: 'dark', - primary: grey, - secondary: grey, - divider: 'rgba(255, 255, 255, 0.2)', - background: { - default: '#232323', - }, - text: { - primary: '#ffffff', - secondary: grey[500], - }, - error: red, - info: lightblue, - success: green, - warning: orange, - button: { - primary: 'rgba(255, 255, 255, 0.2)', - primaryText: '#ffffff', - disabled: 'rgba(255, 255, 255, 0.1)', - disabledText: 'rgba(255, 255, 255, 0.4)', - action: orange[300], - actionText: '#000000', - hover: 'rgba(255, 255, 255, 0.7)', - }, - options: { - hover: '#474747', - select: '#5b5b5b', - }, - card: { - background: '#333333', - secondary: '#474747', - elevation: 'none', - }, - popover: { - background: '#1b2033', - secondary: 'rgba(255, 255, 255, 0.5)', - elevation: 'none', - }, - modal: { - background: '#474747', - }, - font: { - primary: 'Impact', - header: 'Impact', - }, -}; +This guide covers the key considerations and step-by-step process for upgrading the MultiGov Staking Program, including updating the program binary, Interface Description Language (IDL), and `HubProposalMetadata` while ensuring cross-chain compatibility. -export default function App() { - return ; -} -``` +## Key Considerations for Upgrades -### Environment {: #environment } +- **Program upgradeability** - you can upgrade the MultiGov Staking Program on Solana using the `anchor upgrade` command + - You need the program's new bytecode (`.so` file) and an updated IDL file to reflect any changes in the program's interface to complete an upgrade + - The program's authority (deployer) must execute the upgrade -You can configure Connect to be used in Testnet environments, too. You can toggle between Mainnet and Testnet environments by defining the `WormholeConnectConfig` as follows: +- **`HubProposalMetadata`** - can be updated without redeploying the entire program. You can do this by invoking the `updateHubProposalMetadata` instruction + - You must carefully validate updates to `HubProposalMetadata` to ensure compatibility with the existing system -=== "Mainnet" +- **Cross-chain compatibility** - ensure any changes to the Solana program do not break compatibility with the Ethereum-based `HubGovernor` + - Test upgrades thoroughly on devnet before deploying to mainnet - ```ts - const config: WormholeConnectConfig = { - env: 'mainnet', - }; - ``` +## Upgrade the MultiGov Program -=== "Testnet" +Follow these steps to upgrade the MultiGov Staking Program on Solana: - ```ts - const config: WormholeConnectConfig = { - env: 'testnet', - }; +1. **Prepare the new program binary** - build the updated program using the provided script + + ```bash + ./scripts/build_verifiable_staking_program.sh ``` -### Custom RPC Endpoint {: #custom-rpc-endpoint } -You can define a custom RPC provider for your Connect widget to use. This can be especially helpful if you'd like to replace public endpoints with dedicated or private endpoints. + The new program binary will be located at: -```ts -const config: WormholeConnectConfig = { - rpcs: { - solana: 'https://rpc.ankr.com/solana/ee827255553bb0fa9e0aaeab27e988707e60ea06ae36be0658b778072e94979e', - }, -}; -``` + ```bash + target/deploy/staking.so + ``` -### Arbitrary Token {: #arbitrary-token } +2. **Upgrade the program** - use the anchor upgrade command to deploy the new program binary -The following section shows how to add an arbitrary token to your deployment of Connect. + ```bash + anchor upgrade --program-id INSERT_PROGRAM_ID --provider.cluster INSERT_CLUSTER_URL INSERT_PATH_TO_PROGRAM_BINARY + ``` -!!! note - You will need to [register](https://portalbridge.com/advanced-tools/#/register){target=\_blank} your token with the Token Bridge to get the contract addresses necessary for it to work with Connect. + Your completed anchor upgrade command should resemble the following: + ```bash + anchor upgrade --program-id DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY --provider.cluster https://api.devnet.solana.com ./target/deploy/staking.so + ``` -This example configuration limits Connect to the Solana and Ethereum networks and a handful of tokens, including `BSKT`, which isn't built in by default and provided under the `tokensConfig` key. +3. **Update the IDL** - after upgrading the program, update the IDL to reflect any changes in the program's interface -See [`src/config/types.ts`](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. + ```bash + anchor idl upgrade INSERT_PROGRAM_ID --filepath INSERT_PATH_TO_IDL_FILE + ``` -```json -const config: WormholeConnectConfig = { - networks: ['solana', 'ethereum'], - tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC', 'BSKT'], - tokensConfig: { - BSKT: { - key: 'BSKT', - symbol: 'BSKT', - nativeChain: 'solana', - tokenId: { - chain: 'solana', - address: '6gnCPhXtLnUD76HjQuSYPENLSZdG8RvDB1pTLM5aLSJA', - }, - coinGeckoId: 'basket', - icon: 'https://assets.coingecko.com/coins/images/34661/standard/BSKT_Logo.png?1705636891', - color: '#2894EE', - decimals: { - default: 5, - }, - }, - }, -}; -``` + Your completed IDL upgrade command should resemble the following: + ```bash + anchor idl upgrade --provider.cluster https://api.devnet.solana.com --filepath ./target/idl/staking.json DgCSKsLDXXufYeEkvf21YSX5DMnFK89xans5WdSsUbeY + ``` -## More Configuration Options {: #more-configuration-options } +4. **Update `HubProposalMetadata`** - if `HubProposalMetadata` requires an update, run the following script to invoke the `updateHubProposalMetadata` instruction and apply the changes -### Whitelisting Tokens {: #whitelisting-tokens } + ```bash + npx ts-node app/deploy/07_update_HubProposalMetadata.ts + ``` +--- END CONTENT --- -By default, Connect will offer its complete built-in list of assets, but you can restrict the displayed assets by defining a subset of tokens under `tokens`. The default full list is as follows: +Doc-Content: https://wormhole.com/docs/products/multigov/overview/ +--- BEGIN CONTENT --- +--- +title: MultiGov Overview +description: Enable multichain governance with MultiGov. Create, vote, and execute DAO proposals securely across Wormhole supported networks. +categories: Multigov +--- -| Mainnet | Testnet | -|:--------------:|:----------------------------------:| -| ETH | ETH, ETHsepolia | -| WETH | WETH, WETHsepolia | -| USDCeth | USDCeth | -| WBTC | - | -| USDT | - | -| DAI | - | -| BUSD | - | -| MATIC | MATIC | -| WMATIC | WMATIC | -| USDCpolygon | - | -| BNB | BNB | -| WBNB | WBNB | -| USDCbnb | - | -| AVAX | AVAX | -| WAVAX | WAVAX | -| USDCavax | USDCavax | -| FTM | FTM | -| WFTM | WFTM | -| CELO | CELO | -| GLMR | GLMR | -| WGLMR | WGLMR | -| SOL | WSOL | -| PYTH | - | -| SUI | SUI | -| USDCsol | - | -| APT | APT | -| ETHarbitrum | ETHarbitrum, ETHarbitrum_sepolia | -| WETHarbitrum | WETHarbitrum, WETHarbitrum_sepolia | -| USDCarbitrum | USDCarbitrum | -| ETHoptimism | ETHoptimism, ETHoptimism_sepolia | -| WETHoptimism | WETHoptimism, WETHoptimism_sepolia | -| USDCoptimism | USDCoptimism | -| ETHbase | ETHbase, ETHbase_sepolia | -| WETHbase | WETHbase, WETHbase_sepolia | -| tBTC | tBTC | -| tBTCpolygon | tBTCpolygon | -| tBTCoptimism | tBTCoptimism | -| tBTCarbitrum | tBTCarbitrum | -| tBTCbase | tBTCbase | -| tBTCsol | tBTCsol | -| WETHpolygon | - | -| WETHbsc | - | -| wstETH | wstETH | -| wstETHarbitrum | - | -| wstETHoptimism | - | -| wstETHpolygon | - | -| wstETHbase | - | +# MultiGov Overview -### Routes {: #routes } +MultiGov is a multichain governance system that enables decentralized decision-making across multiple blockchain networks. Built on Wormhole messaging, it allows DAOs to manage proposals, voting, and execution from any connected chain without relying on a single hub or bridging assets. It empowers true multichain governance by aggregating voting power across chains and coordinating secure proposal execution. -By default, Connect will offer its complete built-in list of routes, but you can restrict the possible route assets by defining a subset under `routes.` By default, Connect will offer its complete built-in list: +## Key Features -| Mainnet | Testnet | -|:------------:|:----------:| -| bridge | bridge | -| relay | relay | -| cctpManual | cctpManual | -| cctpRelay | cctpRelay | -| nttManual | nttManual | -| nttRelay | nttRelay | -| ethBridge | - | -| wstETHBridge | - | -| usdtBridge | - | -| tBTC | tBTC | +MultiGov expands DAO governance across blockchains, increasing participation, improving security with Wormhole messaging, and enabling unified decision-making at scale. Key features include: -### Wallet Set Up {: #wallet-connect-project-id } +- **Multichain governance**: Token holders can vote and execute proposals from any supported chain. +- **Hub-and-spoke model**: Proposals are created on a central hub chain and voted on from spoke chains, where governance tokens live. +- **Secure vote aggregation**: Vote weights are checkpointed and verified to prevent double voting. +- **Cross-chain proposal execution**: Approved proposals can be executed across multiple chains. +- **Flexible architecture**: Can integrate with any Wormhole-supported blockchain. +- **Upgradeable and extensible**: Supports upgrades across components while preserving vote history and system continuity. +- **Backed by Tally**: Proposal creation, voting, and execution are coordinated via [Tally](https://www.tally.xyz/get-started){target=\_blank}. -When using Wormhole Connect, your selected blockchain network determines the available wallet options. +## How It Works - - For EVM chains, wallets like MetaMask and WalletConnect are supported - - For Solana, you'll see options such as Phantom, Torus, and Coin98 +1. **Create proposal on hub chain**: Proposals are created on the hub chain, which manages the core governance logic, including vote aggregation and execution scheduling. +2. **Vote from spoke chains**: Token holders on spoke chains vote locally using `SpokeVoteAggregators`, with checkpoints tracking their voting power. +3. **Transmit votes via Wormhole**: Votes are securely sent to the hub using [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}, ensuring message integrity and cross-chain verification. +4. **Aggregate and finalize on hub**: The hub chain receives votes from all spokes, tallies results, and finalizes the outcome once the voting period ends. +5. **Execute actions across chains**: Upon approval, proposals can trigger execution on one or more chains, again using [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} to deliver commands. -The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. + -If you would like to offer WalletConnect as a supported wallet option, you'll need to obtain a project ID on the [WalletConnect cloud dashboard](https://cloud.walletconnect.com/){target=\_blank}. +## Use Cases -### Toggle Hamburger Menu {: #toggle-hamburger-menu } +- **Cross-Chain Treasury Management** -By setting the `showHamburgerMenu` option to **false**, you can deactivate the hamburger menu, causing the links to be positioned at the bottom. + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Vote on treasury actions from any supported chain. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Transmit proposal execution to target chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Optionally move assets. -#### Add Extra Menu Entry {: #add-extra-menu-entry } +- **Coordinated Protocol Upgrades Across Chains** -By setting the `showHamburgerMenu` option to `false,` you can add extra links. The following properties are accessed through the `menu[]` property (e.g., `menu[].label`): + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Create a unified proposal to upgrade contracts across networks. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Send upgrade instructions as VAAs and deliver execution payloads to target chains. + +- **Progressive Decentralization for Multichain DAOs** -| Property | Description | -|:--------:|:-------------------------------------------:| -| `label` | Link name to show up | -| `href` | Target URL or URN | -| `target` | Anchor standard target, by default `_blank` | -| `order` | Order where the new item should be injected | + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Extend governance to new chains while preserving coordination. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch on-chain vote weights from remote spokes. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Aggregate results and execute actions via the hub. -#### Sample Configuration {: #sample-configuration } +## Next Steps -```json -{ - "showHamburgerMenu": false, - "menu": [ - { - "label": "Advance Tools", - "href": "https://portalbridge.com", - "target": "_self", - "order": 1 - } - ] -} -``` +Follow these steps to get started with MultiGov: -### CoinGecko API Key {: #coingecko-api-key } +[timeline(wormhole-docs/.snippets/text/products/multigov/multigov-timeline.json)] +--- END CONTENT --- -The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. +Doc-Content: https://wormhole.com/docs/products/multigov/tutorials/treasury-proposal/ +--- BEGIN CONTENT --- +--- +title: MultiGov Guides +description: Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. +categories: MultiGov +--- -### More Networks {: #more-networks } +# Cross-Chain treasury management proposal -Specify a set of extra networks to be displayed on the network selection modal, each linking to a different page, dApp, or mobile app the user will be redirected to. The following properties are accessed through the `moreNetworks` property (e.g., `moreNetworks.href`): +This guide walks through the process of creating and executing a cross-chain governance proposal to mint W tokens to both the Optimism and Arbitrum treasuries. In this tutorial, we'll cover how to create a proposal on the hub chain (Ethereum Mainnet), cast votes from spoke chains (Optimism and Arbitrum), aggregate votes, and execute the proposal. -|
Property
| Description | -|:--------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------:| -| `href` | **Required**. Default value for missing network hrefs | -| `target` | Default value for missing network link targets. Defaults to `_self` | -| `description` | Brief description that should be displayed as a tooltip when the user hovers over a more network icon. Used as default for missing network descriptions | -| `networks[].icon` | **Required**. URL data encoded icon to display | -| `networks[].href` | Network href to redirect to. If present, the values `sourceChain` and `targetChain` are replaced with the currently selected chains before redirecting | -| `networks[].label` | **Required**. Display text | -| `networks[].name` | Unique network key. Defaults to a snake_case version of the label | -| `networks[].description` | Description value. Defaults to `moreNetworks.description` | -| `networks[].target` | href target value. Defaults to `moreNetworks.target` | -| `networks[].showOpenInNewIcon` | Disable top right open in new icon. Defaults to **true** if target is `_blank` or **false** if target is `_self` | +## Create a Proposal -??? code "View full configuration" - ```json - { - ... - "moreNetworks": { - "href": "https://example.com", - "target": "_blank", - "description": "brief description that should be displayed as tooltip when the user hovers over a more network icon", - "networks": [ - { - "icon": "https://assets.coingecko.com/coins/images/34661/standard/BSKT_Logo.png?1705636891", - "name": "more", - "label": "More networks", - "href": "https://portalbridge.com/#/transfer", - "showOpenInNewIcon": false - } - ] - } - ... -} - ``` +The first step is to create a proposal on the hub chain, which in this case is Ethereum Mainnet. The proposal will contain instructions to mint 10 W tokens to the Optimism treasury and 15 ETH to the Arbitrum treasury. -### More Tokens {: #more-tokens } +In the following code snippet, we initialize the proposal with two transactions, each targeting the Hub's Message Dispatcher contract. These transactions will relay the governance actions to the respective spoke chains via Wormhole. -Show a particular entry on the select tokens modal, redirecting the user to a different page, dApp, or mobile app. The following properties are accessed through the `moreTokens` property (e.g., `moreTokens.label`): +Key actions: -| Property | Description | -|:--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------:| -| `label` | **Required**. Display text | -| `href` | **Required**. URL to redirect to. If present, the values `sourceChain` and `targetChain` are replaced with the currently selected chains before redirecting | -| `target` | href target. Defaults to `_self` | +- Define the proposal targets (two transactions to the Message Dispatcher) +- Set values for each transaction (in this case, both are 0 as we're not transferring any native ETH) +- Encode the calldata for minting 10 W tokens on Optimism and sending 15 ETH to Arbitrum +- Finally, we submit the proposal to the `HubGovernor` contract -### Explorer {: #explorer } +```solidity +HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); +// Prepare proposal details +address[] memory targets = new address[](2); +targets[0] = HUB_MESSAGE_DISPATCHER_ADDRESS; +targets[1] = HUB_MESSAGE_DISPATCHER_ADDRESS; +uint256[] memory values = new uint256[](2); +values[0] = 0; +values[1] = 0; +bytes[] memory calldatas = new bytes[](2); +// Prepare message for Optimism to mint 10 W tokens +// bytes created using abi.encodeWithSignature("mint(address,uint256)", 0xB0fFa8000886e57F86dd5264b9582b2Ad87b2b91, 10e18) +calldatas[0] = abi.encodeWithSignature( + "dispatch(bytes)", + abi.encode( + OPTIMISM_WORMHOLE_CHAIN_ID, + [OPTIMISM_WORMHOLE_TREASURY_ADDRESS], + [uint256(10 ether)], + [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] + ) +); +// Prepare message for Arbitrum to receive 15 ETH +calldatas[1] = abi.encodeWithSignature( + "dispatch(bytes)", + abi.encode( + ARBITRUM_WORMHOLE_CHAIN_ID, + [ARBITRUM_WORMHOLE_TREASURY_ADDRESS], + [uint256(15 ether)], + [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] + ) +); +string memory description = "Mint 10 W to Optimism treasury and 10 W to Arbitrum treasury via Wormhole"; +// Create the proposal +uint256 proposalId = governor.propose( + targets, values, calldatas, description +) +``` -Enable the explorer button to allow users to search for their transactions on a given explorer, filtering by their wallet address. The following properties are accessed through the `explorer` property (e.g., `explorer.label`): +??? interface "Parameters" -| Property | Description | -|:--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| `label` | Display text. Defaults to `Transactions` | -| `href` | **Required**. URL of the explorer, for instance [https://wormholescan.io/](https://wormholescan.io/){target=\_blank}. If present, the value `address` is replaced with the connected wallet address | -| `target` | `href` target. Defaults to `_blank` | ---- END CONTENT --- + `GOVERNOR_ADDRESS` ++"address"++ -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-data/ ---- BEGIN CONTENT --- ---- -title: Connect Data Configuration -description: Configure Wormhole Connect v1 (latest) with custom chains, tokens, routes, and more for enhanced blockchain interoperability. -categories: Connect, Transfer ---- + The address of the `HubGovernor` contract on Ethereum Mainnet. -## Data Configuration + --- -This page explains how to configure Wormhole Connect's core functionality, from choosing supported chains and tokens to bridging routes to setting up wallets and enabling price lookups. By the end, you'll know how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. + `targets` ++"address[]"++ -## Get Started + An array that specifies the addresses that will receive the proposal's actions. Here, both are set to the `HUB_MESSAGE_DISPATCHER_ADDRESS`. -Configure Wormhole Connect by passing a `WormholeConnectConfig` object as the `config` prop. + --- -=== "React integration" + `values` ++"uint256[]"++ - ```ts - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + An array containing the value of each transaction (in Wei). In this case, both are set to zero because no ETH is being transferred. -const config: WormholeConnectConfig = { - chains: ['Ethereum', 'Polygon', 'Solana'], - tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], - rpcs: { - Ethereum: 'https://rpc.ankr.com/eth', - Solana: 'https://rpc.ankr.com/solana', - } -} + --- - - ``` + `calldatas` ++"bytes[]"++ -=== "Hosted integration" + The calldata for the proposal. These are encoded contract calls containing cross-chain dispatch instructions for minting tokens and sending ETH. The calldata specifies minting 10 W tokens to the Optimism treasury and sending 15 ETH to the Arbitrum treasury. - ```ts - import WormholeConnect, { - wormholeConnectHosted, - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + --- -const config: WormholeConnectConfig = { - chains: ['Ethereum', 'Polygon', 'Solana'], - tokens: ['ETH', 'WETH', 'MATIC', 'WMATIC'], - rpcs: { - Ethereum: 'https://rpc.ankr.com/eth', - Solana: 'https://rpc.ankr.com/solana', - }, -}; - -const container = document.getElementById('bridge-container'); + `description` ++"string"++ -wormholeConnectHosted(container, { - config, -}); - ``` + A description of the proposal, outlining the intent to mint tokens to Optimism and send ETH to Arbitrum. -!!! note - The complete type definition of `WormholeConnectConfig` is available in the [Wormhole Connect repository](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank}. +??? interface "Returns" -## Examples {: #examples } + `proposalId` ++"uint256"++ -### Configuring Chains and RPC Endpoints {: #chains-and-rpc-endpoints } + The ID of the newly created proposal on the hub chain. -Connect lets you customize the available chains to match your project's needs. You should provide your own RPC endpoints, as the default public ones may not support essential functions like balance fetching. +## Vote on the Proposal via Spoke -=== "Mainnet" +Once the proposal is created on the hub chain, stakeholders can cast their votes on the spoke chains. This snippet demonstrates how to connect to a spoke chain and cast a vote for the proposal. The voting power (weight) is calculated based on each stakeholder's token holdings on the spoke chain. - ```js - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +Key actions: -const config: WormholeConnectConfig = { - chains: ['Ethereum', 'Polygon', 'Solana'], - rpcs: { - Ethereum: 'https://rpc.ankr.com/eth', - Solana: 'https://rpc.ankr.com/solana', - }, -}; +- Connect to the `SpokeVoteAggregator` contract on the spoke chain. This contract aggregates votes from the spoke chains and relays them to the hub chain +- Cast a vote in support of the proposal -function App() { - return ; -} - ``` +```solidity +// Connect to the SpokeVoteAggregator contract of the desired chain +SpokeVoteAggregator voteAggregator = SpokeVoteAggregator(VOTE_AGGREGATOR_ADDRESS); +// Cast a vote +uint8 support = 1; // 1 for supporting, 0 for opposing +uint256 weight = voteAggregator.castVote(proposalId, support); +``` -=== "Testnet" +??? interface "Parameters" - ```js - import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + `VOTE_AGGREGATOR_ADDRESS` ++"address"++ -const config: WormholeConnectConfig = { - // You can use Connect with testnet chains by specifying "network": - network: 'Testnet', - chains: ['Sepolia', 'ArbitrumSepolia', 'BaseSepolia', 'Avalanche'], - rpcs: { - Avalanche: 'https://rpc.ankr.com/avalanche_fuji', - BaseSepolia: 'https://base-sepolia-rpc.publicnode.com', - }, -}; + The address of the `SpokeVoteAggregator` contract on the spoke chain (Optimism or Arbitrum). -function App() { - return ; -} - ``` + --- -!!! note - For a complete list of available chain names, see the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank}. + `proposalId` ++"uint256"++ -### Configuring Routes + The ID of the proposal created on the hub chain, which is being voted on. -By default, Connect offers two bridging protocols: Token Bridge (for Wormhole-wrapped tokens) and Circle's CCTP (for native USDC). For most use cases, integrators require more than these default routes. The `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including default and third-party routes. + --- -#### Available Route Plugins + `support` ++"uint8"++ -The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: + The vote being cast (`1` for supporting the proposal, `0` for opposing). -- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank} - manually redeemed Wormhole Token Bridge route -- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank} - automatically redeemed (relayed) Token Bridge route -- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank} - manually redeemed CCTP route -- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank} - automatically redeemed (relayed) CCTP route -- **`DEFAULT_ROUTES`** - array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`) -- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank} - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route -- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}- function that returns the manually-redeemed NTT route -- **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array -- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank} - route that offers multiple Mayan protocols -- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank} - route for Mayan's Swift protocol only -- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank} - route for Mayan's MCTP protocol only -- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank} - route for Mayan's original Wormhole transfer protocol +??? interface "Returns" -In addition to these routes, developers can create custom routes for their Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. + `weight` ++"uint256"++ -For further details on the `route` plugin interface, refer to the [Wormhole TypeScript SDK route code](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/route.ts){target=\_blank}. + The weight of the vote, determined by the voter’s token holdings on the spoke chain. -#### Example: Offer Only CCTP Transfers +## Vote Aggregation -To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: +In the background process, votes cast on the spoke chains are aggregated and sent back to the hub chain for final tallying. This is typically handled off-chain by a "crank turner" service, which periodically queries the vote status and updates the hub chain. -```typescript -import WormholeConnect, { - AutomaticCCTPRoute, - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +Key actions: -const config: WormholeConnectConfig = { - routes: [AutomaticCCTPRoute], -}; +- Aggregate votes from different chains and submit them to the hub chain for tallying -; +```solidity +// Aggregate votes sent to Hub (this would typically be done by a "crank turner" off-chain) +hubVotePool.crossChainVote(queryResponseRaw, signatures); ``` -#### Example: Offer All Default Routes and Third-Party Plugins - -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. - -```typescript -import WormholeConnect, { - DEFAULT_ROUTES, - nttRoutes, - MayanRouteSWIFT, - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; - -import { myNttConfig } from './consts'; // Custom NTT configuration +??? interface "Parameters" -const config: WormholeConnectConfig = { - routes: [...DEFAULT_ROUTES, ...nttRoutes(myNttConfig), MayanRouteSWIFT], -}; + `queryResponseRaw` ++"bytes"++ -; -``` + The raw vote data from the spoke chains. -This flexible plugin allows you to combine default routes (such as Token Bridge and CCTP) with third-party protocols, offering complete control over which routes are available in your application. + --- -### Adding Custom Tokens {: #custom-tokens } + `signatures` ++"bytes"++ -The following section shows how to add an arbitrary token to your deployment of Connect. + Cryptographic signatures that verify the validity of the votes from the spoke chains. -!!! note - You will need to [register](https://portalbridge.com/advanced-tools/#/register){target=\_blank} your token with the Token Bridge to get the contract addresses necessary for it to work with that protocol. +## Execute Proposal and Dispatch Cross-Chain Messages -This example configuration adds the BONK token to Connect. Note the `wrappedTokens` property, which is required for use with the Token Bridge. +After the proposal passes and the votes are tallied, the next step is to execute the proposal. The `HubGovernor` contract will dispatch the cross-chain messages to the spoke chains, where the respective treasuries will receive the tokens. -See the [Connect source code](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. +Key actions: -```typescript -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +- Execute the proposal after the voting period ends and the proposal passes +- The `execute` function finalizes the proposal execution by dispatching the cross-chain governance actions. The `descriptionHash` ensures that the executed proposal matches the one that was voted on. -const config: WormholeConnectConfig = { - tokensConfig: { - BONK: { - key: 'BONK', - symbol: 'BONK', - nativeChain: 'Ethereum', - icon: Icon.ETH, - tokenId: { - chain: 'Ethereum', - address: '0x1151CB3d861920e07a38e03eEAd12C32178567F6', - }, - coinGeckoId: 'bonk', - decimals: 18, - }, - }, - wrappedTokens: { - BONK: { - Solana: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', - }, - }, -}; +```solidity +HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); +// Standard timelock execution +governor.execute(targets, values, calldatas, descriptionHash); ``` -### Whitelisting Tokens {: #whitelisting-tokens } +??? interface "Parameters" -Connect offers a list of built-in tokens by default. You can see it below: + `governor` ++"HubGovernor"++ -- [Mainnet tokens](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/mainnet/tokens.ts){target=\_blank} -- [Testnet tokens](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/testnet/tokens.ts){target=\_blank} + The `HubGovernor` contract instance. -You can customize the tokens shown in the UI using the `tokens` property. The following example adds a custom token and limits Connect to showing only that token, along with the native gas tokens ETH and SOL. + --- -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + `targets` ++"address[]"++ -const config: WormholeConnectConfig = { - chains: ['Ethereum', 'Solana'], - tokens: ['ETH', 'SOL', 'BONK'], - rpcs: { - Ethereum: 'https://rpc.ankr.com/eth', - Solana: 'https://rpc.ankr.com/solana', - }, - tokensConfig: { - BONK: { - key: 'BONK', - symbol: 'BONK', - icon: 'https://assets.coingecko.com/coins/images/28600/large/bonk.jpg?1696527587', - tokenId: { - chain: 'Ethereum', - address: '0x1151CB3d861920e07a38e03eEAd12C32178567F6', - }, - decimals: 18, - }, - }, - wrappedTokens: { - BONK: { - Solana: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', - }, - }, -}; + An array containing the target addresses for the proposal’s transactions (in this case, the `HUB_MESSAGE_DISPATCHER_ADDRESS` for both). -function App() { - return ; -} -``` + --- -You can whitelist tokens by symbol or by specifying tuples of [chain, address]. For example, this would show only BONK token (on all chains you've whitelisted) as well as [`EPjFW...TDt1v`](https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v){target=\_blank} on Solana, which is USDC. + `values` ++"uint256[]"++ -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + An array of values (in Wei) associated with each transaction (both are zero in this case). -const config: WormholeConnectConfig = { - chains: ['Ethereum', 'Solana'], - tokens: [ - // Whitelist BONK on every whitelisted chain - 'BONK', - // Also whitelist USDC, specifically on Solana - ['Solana', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'] - ], - ... -}; + --- -function App() { - return ; -} -``` + `calldatas` ++"bytes[]"++ -### User-Inputted Tokens {: #user-inputted-tokens } + The encoded transaction data to dispatch the governance actions (e.g., minting tokens and transferring ETH). -As of version 2.0, Connect allows users to paste token addresses to bridge any token they want. As an integrator, you may want to disable this feature if you are deploying Connect for use only with a specific token(s). + --- -If you provide a token whitelist (see above), this is turned off automatically. However, you can also disable it explicitly like this: + `descriptionHash` ++"bytes32"++ -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + A hash of the proposal’s description, used to verify the proposal before execution. -const config: WormholeConnectConfig = { - ui: { - disableUserInputtedTokens: true - } -}; +??? interface "Returns" -function App() { - return ; -} -``` + No direct return, but executing this function finalizes the cross-chain governance actions by dispatching the encoded messages via Wormhole to the spoke chains. -Setting `ui.disableUserInputtedTokens` to `true` will disable the ability to paste in token addresses. - -### Transaction Settings {: #transaction-settings } +Once the proposal is executed, the encoded messages will be dispatched via Wormhole to the spoke chains, where the Optimism and Arbitrum treasuries will receive their respective funds. +--- END CONTENT --- -Landing transactions on Solana can require finely tuned priority fees when there is congestion. You can tweak how Connect determines these with `transactionSettings`. All of the parameters in this configuration are optional; you can provide any combination of them. +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/architecture/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Architecture +description: Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. +categories: NTT, Transfer +--- -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +## Introduction -const config: WormholeConnectConfig = { - transactionSettings: { - Solana: { - priorityFee: { - // Number between 0-1, defaults to 0.9. Higher percentile yields higher fees. - // For example, you can set percentile to 0.95 to make Connect compute the - // 95th percentile priority fee amount based on recent transactions - percentile: 0.95, +The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. - // Any number, defaults to 1.0. The fee amount is multiplied by this number. - // This can be used to further raise or lower the fees Connect is using. - // For example, percentile=0.95 and percentileMultiple=1.1 would use - // the 95th percentile fee, with a 10% increase - percentileMultiple: 1.1, - // Minimum fee you want to use in microlamports, regardless of recent transactions - // Defaults to 1 - min: 200_000, +## System Components - // Maximum fee you want to use in microlamports, regardless of recent transactions - // Defaults to 100,000,000 - max: 5_000_000, - } - } - } -}; +The NTT framework is composed of managers, which oversee the transfer process, and transceivers, which handle cross-chain messaging, ensuring smooth and reliable token transfers. -function App() { - return ; -} -``` +### Managers -!!! note - Connect can calculate fees more accurately if you are using a [Triton](https://triton.one){target=\_blank} RPC endpoint. +_Managers_ are responsible for handling the flow of token transfers between different blockchains and ensuring that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. The main tasks of managers include rate-limiting transactions, verifying message authenticity (message attestation), and managing the interaction between multiple transceivers, who are responsible for cross-chain communications. -### Wallet Set Up {: #reown-cloud-project-id } +Each manager is assigned to a specific token but can operate across multiple chains. Their key responsibility is to ensure that tokens are securely locked or burned on the source chain before being minted or unlocked on the destination chain. This provides the integrity of token transfers and prevents double-spending. -Your selected blockchain network determines the available wallet options when using Wormhole Connect. +A manager is responsible for: - - For EVM chains, wallets like MetaMask and Reown Cloud (formerly WalletConnect) are supported - - For Solana, you'll see options such as Phantom, Torus, and Coin98 +- **Handling token transfer flow** - upon a transfer request, `NttManager` either locks or burns tokens depending on the configuration, emits a `TransferSent` event, and ensures tokens can’t be accessed on the source chain before leasing them on the destination chain. This process safeguards against double-spending and maintains a secure transfer +- **Rate-limiting** - the `NttManager` contract includes rate-limiting functionality to prevent overloading the network or flooding the target chain. The `NttManager` applies rate limits to manage transfer flow and prevent network congestion. Limits apply to both outgoing and incoming transfers + - **Outbound** - transfers exceeding the outbound limit are queued (if `shouldQueue` is true) or reverted + - **Inbound** - similar limits apply on the destination chain, delaying transfers if capacity is exceeded -The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. + Rate limit duration and queuing are customizable per chain, and events notify users when transfers hit the limit -If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. +- **Message authenticity verification** - the `NttManager` ensures transfer security by verifying message authenticity through multiple attestations from transceivers. For each transfer, a threshold number of attestation signatures must be gathered from transceivers. Once verified, `NttManager` releases tokens on the destination chain, ensuring only authenticated transfers are processed +- **Interaction with transceivers** - `NttManager` collaborates with transceivers, forwarding transfer messages between chains and handling message verification. Transceivers route messages with transfer details to the destination chain, coordinating with `NttManager` to verify that tokens are locked or burned before releasing them on the other side. Transceivers can be customized to work with different security protocols, adding flexibility -### CoinGecko API Key {: #coingecko-api-key } +### Transceivers -The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. +_Transceivers_ facilitate cross-chain token transfers by ensuring the accurate transmission of messages between different blockchains. They work in conjunction with managers to route token transfers from the source chain to the recipient chain. Their primary function is to ensure that messages regarding the transfer process are delivered correctly, and that tokens are safely transferred across chains. -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +While transceivers operate closely with Wormhole's ecosystem, they can also be configured independently of Wormhole's core system, allowing for flexibility. This adaptability allows them to be integrated with various verification backends to accommodate different security needs or platform-specific requirements. -const config: WormholeConnectConfig = { - coinGeckoApiKey: 'INSERT_API_KEY', -}; +Transceivers are entrusted with several responsibilities: -function App() { - return ; -} -``` ---- END CONTENT --- +- **Message transmission** - transceivers handle the routing of transfer messages between chains. When a transfer is initiated, the transceiver sends the message (including transfer details like recipient and amount) to the destination chain’s manager for verification and processing +- **Manager coordination** - transceivers work with managers to ensure tokens are locked or burned on the source chain before issuance on the destination chain, reinforcing the security of each transfer +- **Custom verification support** - transceivers can integrate with custom verification backends, allowing flexibility to adapt to different security protocols or chain requirements. This customization enables protocols to use different attestation standards as needed -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/configure-theme/ ---- BEGIN CONTENT --- ---- -title: Connect Theme & UI Customization -description: Learn how to style Wormhole Connect with custom color schemes, fonts, layouts, and menus for a streamlined user experience. -categories: Connect, Transfer ---- +How it works: -## Theme & UI Customization +1. The transceiver receives instructions from the manager to send messages across chains +2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred +3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain -This page focuses on how to style the Wormhole Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. +![NTT architecture diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-1.webp) -### Changing the Color Scheme +!!! note + [Learn more](/docs/products/native-token-transfers/concepts/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. -You can customize Connect's color scheme by providing a `theme` prop. +#### Custom Transceivers -=== "React integration" +The NTT framework supports advanced features such as custom transceivers for specialized message verification, enhancing security and adaptability. The architecture includes detailed processes for initiating transfers, managing rate limits, and finalizing token operations, with specific instructions and events outlined for EVM-compatible chains and Solana. - ```ts - import WormholeConnect, { - WormholeConnectConfig, - WormholeConnectTheme, -} from '@wormhole-foundation/wormhole-connect'; +NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. -const config: WormholeConnectConfig = { - /* Your config... */ -}; +![Custom Attestation with NTT diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-2.webp) -const theme: WormholeConnectTheme = { - mode: 'dark', - primary: '#78c4b6', - font: 'Comic Sans; sans-serif', -}; +The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. -function App() { - return ; -} - ``` +For more details, to collaborate, or to see examples of custom transceivers, [contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors. -=== "Hosted integration" +## Lifecycle of a Message - ```ts - import WormholeConnect, { - WormholeConnectConfig, - WormholeConnectTheme, - wormholeConnectHosted, -} from '@wormhole-foundation/wormhole-connect'; +The lifecycle of a message in the Wormhole ecosystem for Native Token Transfers (NTT) involves multiple steps to ensure secure and accurate cross-chain token transfers. This lifecycle can vary depending on the blockchain being used, and the following explanations focus on the EVM and Solana implementations. The key stages include initiating the transfer, handling rate limits, sending and receiving messages, and finally, minting or unlocking tokens on the destination chain. -const config: WormholeConnectConfig = { - /* Your config... */ -}; +### Transfer -const theme: WormholeConnectTheme = { - mode: 'dark', - primary: '#78c4b6', - font: 'Comic Sans; sans-serif', -}; +The process begins when a client initiates a transfer. For EVM, this is done using the `transfer` function, whereas in Solana, the client uses either the `transfer_lock` or `transfer_burn` instruction, depending on whether the program is in locking or burning mode. The client specifies the transfer amount, recipient chain ID, recipient address, and a flag (`should_queue` on both EVM and Solana) to decide whether the transfer should be queued if it hits the rate limit. -const container = document.getElementById('bridge-container'); +In both cases: -wormholeConnectHosted(container, { - config, - theme, -}); - ``` +- If the source chain is in locking mode, the tokens are locked on the source chain to be unlocked on the destination chain +- If the source chain is in burning mode, the tokens are burned on the source chain, and new tokens are minted on the destination chain -The `WormholeConnectTheme` type supports the following properties: +Once initiated, an event (such as `TransferSent` on EVM or a corresponding log on Solana) is emitted to signal that the transfer process has started. -|
Property
| Description | Example | -|:--------------------------------------:|:---------------------------------------------------------------------:|:---------------------:| -| `mode` | Dark mode or light mode. **Required** | `"dark"` or `"light"` | -| `input` | Color used for input fields, dropdowns | `"#AABBCC"` | -| `primary` | Primary color used for buttons | `"#AABBCC"` | -| `secondary` | Secondary color used for some UI elements | `"#AABBCC"` | -| `text` | Primary color used for text | `"#AABBCC"` | -| `textSecondary` | Secondary color used for dimmer text | `"#AABBCC"` | -| `error` | Color to display errors in, usually some shade of red | `"#AABBCC"` | -| `success` | Color to display success messages in | `"#AABBCC"` | -| `font` | Font used in the UI, can be custom font available in your application | `"Arial; sans-serif"` | +### Rate Limit -### Toggle Hamburger Menu {: #toggle-hamburger-menu } +Both EVM and Solana implement rate-limiting for transfers to prevent abuse or network overload. Rate limits apply to both the source and destination chains. If transfers exceed the current capacity, depending on whether the `shouldQueue` flag is set to true, they can be queued. -By setting the `showHamburgerMenu` option to **false**, you can deactivate the hamburger menu, which will position the links at the bottom. +- On EVM, the transfer is added to an outbound queue if it hits the rate limit, with a delay corresponding to the configured rate limit duration. If `shouldQueue` is set to false, the transfer is reverted with an error +- On Solana, the transfer is added to an **Outbox** via the `insert_into_outbox method`, and if the rate limit is hit, the transfer is queued with a `release_timestamp`. If `shouldQueue` is false, the transfer is reverted with a `TransferExceedsRateLimit` error -#### Add Extra Menu Entry {: #add-extra-menu-entry } +Both chains emit events or logs when transfers are rate-limited or queued. -By setting the `showHamburgerMenu` option to `false,` you can add extra links. The following properties are accessed through the `menu[]` property (e.g., `menu[].label`): +### Send -| Property | Description | -|:--------:|:-------------------------------------------:| -| `label` | Link name to show up | -| `href` | Target URL or URN | -| `target` | Anchor standard target, by default `_blank` | -| `order` | Order where the new item should be injected | +After being forwarded to the Transceiver, the message is transmitted across the chain. Transceivers are responsible for delivering the message containing the token transfer details. Depending on the Transceiver's implementation, messages may be routed through different systems, such as Wormhole relayers or other custom relaying solutions. Once the message is transmitted, an event is emitted to signal successful transmission. -```jsx -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +- In EVM, the message is sent using the `sendMessage` function, which handles the transmission based on the Transceiver's implementation. The Transceiver may use Wormhole relayers or custom relaying solutions to forward the message +- In Solana, the transfer message is placed in an Outbox and released via the `release_outbound` instruction. The Solana transceiver, such as the Wormhole Transceiver, may send the message using the `post_message` instruction, which Wormhole Guardians observe for verification -const config: WormholeConnectConfig = { - ui: { - showHamburgerMenu: false, - menu: [ - { - label: 'Advance Tools', - href: 'https://portalbridge.com', - target: '_self', - order: 1, - }, - ], - }, -}; +In both cases, an event or log (e.g., `SendTransceiverMessage` on EVM or a similar log on Solana) is emitted to signal that the message has been transmitted. -function App() { - return ; -} -``` ---- END CONTENT --- +### Receive -Doc-Content: https://wormhole.com/docs/build/transfers/connect/configuration/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer ---- +Upon receiving the message on the destination chain, an off-chain relayer forwards the message to the destination Transceiver for verification. -# Wormhole Connect +- In EVM, the message is received by the `NttManager` on the destination chain, which verifies the message's authenticity. Depending on the M of N threshold set for the attestation process, the message may require attestations from multiple transceivers +- In Solana, the message is received via the `receive_message` instruction in the Wormhole Transceiver program. The message is verified and stored in a `VerifiedTransceiverMessage` account, after which it is placed in an Inbox for further processing -## Configure Connect +In both chains, replay protection mechanisms ensure that a message cannot be executed more than once. Events or logs are emitted (e.g., `ReceivedMessage` on EVM or `ReceiveMessage` on Solana) to notify that the message has been successfully received. -Wormhole Connect is a flexible React widget that streamlines cross-chain asset transfers and enables seamless interoperability by leveraging Wormhole's powerful infrastructure. Designed for easy integration into decentralized applications (dApps), Wormhole Connect abstracts the complexities of cross-chain communication, providing a user-friendly experience for both developers and end users. +### Mint or Unlock -This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. +Finally, after the message is verified and attested to, the tokens can be either minted (if they were burned on the source chain) or unlocked (if they were locked). The tokens are then transferred to the recipient on the destination chain, completing the cross-chain token transfer process. -!!! note - To upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for instructions. +- On EVM, tokens are either minted (if burned on the source chain) or unlocked (if locked on the source chain). The `TransferRedeemed` event signals that the tokens have been successfully transferred +- On Solana, the tokens are unlocked or minted depending on whether the program is in locking or burning mode. The `release_inbound_unlock` or `release_inbound_mint` instruction is used to complete the transfer, and a corresponding log is produced - If you're using an older version of Wormhole Connect (v0.x), please refer to the [v0.x configuration documentation](/docs/build/transfers/connect/configuration-v0/){target=\_blank}. +In both cases, once the tokens have been released, the transfer process is complete, and the recipient receives the tokens. Events are emitted to indicate that the transfer has been fully redeemed. +--- END CONTENT --- -
+Doc-Content: https://wormhole.com/docs/products/native-token-transfers/concepts/security/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Security +description: Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. +categories: NTT, Transfer +--- -- :octicons-database-16:{ .lg .middle } **Data** +# Security - --- +## Global Accountant - Learn how to configure the networks, tokens, and routes supported by Wormhole Connect. Set up RPC endpoints, whitelist tokens, and leverage multiple bridging protocols to meet your dApp's needs. +The Global Accountant is a defense-in-depth security feature that checks the integrity of every token transfer. It ensures that chain balances remain isolated and more tokens cannot be burned and transferred out of a chain than were ever minted. +This feature ensures native asset fungibility remains in 1:1 parity. At no time will assets coming from a spoke chain exceed the number of native assets sent to that spoke chain. The Guardians, with their role in enforcing accounting transparency, provide a reassuring layer of security, attesting to a Native Token Transfer (NTT) only if it passes integrity checks. - [:custom-arrow: Get started](/docs/build/transfers/connect/configuration/configure-data/) +[Contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors if you are interested in configuring the Global Accountant for your multichain deployment. -- :octicons-apps-16:{ .lg .middle } **Theme** +## Governance and Upgradeability - --- +Integrators should implement governance mechanisms to manage the addition and removal of transceivers and to upgrade contracts using proxy patterns, as demonstrated in the upgrade functions in the `NttManager` contracts. These processes can also set thresholds and rules for attestation and message approval. - Discover how to style the Wormhole Connect widget to align with your brand. Customize colors, fonts, and UI elements to deliver a seamless user experience. +The registry component of the NTT system is crucial for maintaining a trusted list of transceivers and managing their status. Governance processes for the following actions can be submitted directly to the corresponding contract on-chain, whether it is one or multiple of the bridging contracts or one of the token contracts: - [:custom-arrow: Explore routes](/docs/build/transfers/connect/configuration/configure-theme/) +- Adding or removing a transceiver address from the registry +- Setting the token contract address on a bridging contract +- Setting the Wormhole Core Contract address on a bridging contract +- Setting the registered bridging contract address on the token contract -
+This governance model ensures that the system remains secure while being adaptable to new requirements in any environment where it is deployed. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/faqs/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/access-control/ --- BEGIN CONTENT --- --- -title: Connect FAQs -description: Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. -categories: Connect, Transfer +title: Native Token Transfers Access Control +description: Learn about the owner and pauser access roles for the NTT manager contract, which can be used to pause and un-pause token transfers. +categories: NTT, Transfer --- -# Wormhole Connect FAQs +## Owner and Pauser Roles -## What types of assets does Connect support? +Pausing the Native Toke Transfer (NTT) Manager Contract will disallow initiating new token transfers. While the contract is paused, in-flight transfers can still be redeemed (subject to rate limits if configured). -Wormhole Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: +NTT can be paused on a particular chain by updating the `paused` parameter on the deployment to `true` via the NTT CLI, then performing `ntt push` to sync the local configuration with the on-chain deployment. - - Major stablecoins like USDT and USDC (via CCTP) - - Native gas tokens such as ETH, SOL, etc. - - Cross-chain asset swaps through integrators like Mayan +- **Owner** - full control over NTT contracts, can perform administrative functions. Has the ability to un-pause contracts if they have been paused +- **Pauser** - can pause NTT contracts to halt token transfers temporarily. This role is crucial for responding quickly to adverse events without a prolonged governance process. Cannot un-pause contracts -When bridging assets through the Wormhole Token Bridge, depending on the chain and token, assets may arrive as Wormhole-wrapped tokens on the destination chain. +You may verify the current owner, pauser, and paused status of the NTT Manager contract on the `deployment.json` file in your NTT project directory. -## What chains does Connect support? +```json +{ + "network": "Testnet", + "chains": { + "Sepolia": { + "version": "1.1.0", + "mode": "burning", + "paused": true, // set to true to pause the contract + "owner": "0x0088DFAC40029f266e0FF62B82E47A07467A0345", + "manager": "0x5592809cf5352a882Ad5E9d435C6B7355B716357", + //... + "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" + } + } +} +``` -Connect supports around 30 chains, spanning various blockchain runtimes: +!!! note + While the `Pauser` can pause contracts, the ability to un-pause contracts is callable only by the `Owner`. - - EVM-based chains (Ethereum, Base, Arbitrum, BSC, etc.) - - Solana - - Move-based chains (Sui, Aptos) +The `Owner` and the `Pauser` addresses can each pause the contract. Since the contract `Owner` address is typically a multisig or a more complex DAO governance contract, and pausing the contract only affects the availability of token transfers, protocols can choose to set the `Pauser` address to be a different address. Creating a separate `Pauser` helps protocols respond quickly to potential risks without going through a drawn-out process. -For a complete list of supported chains, see the [Connect-supported chains list](/docs/build/transfers/connect/features/){target=\_blank}. +Consider separating `Owner` and `Pauser` roles for your multichain deployment. `Owner` and `Pauser` roles are defined directly on the `NttManager` contract. +--- END CONTENT --- -## What is gas dropoff? +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/configuration/rate-limiting/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Rate Limiting +description: Learn about rate limits in Wormhole NTT by configuring send/receive limits, queuing, and canceling flows to manage multichain token transfers efficiently. +categories: NTT, Transfer +--- -Gas dropoff allows users to receive gas for transaction fees on the destination chain, eliminating the need to acquire the native gas token from a centralized exchange. The relayer automatically swaps part of the transferred assets into the native gas token, enabling seamless entry into new ecosystems. +## Introduction -## Can I customize Connect inside my application? +The Native Token Transfer (NTT) framework provides configurable per-chain rate limits for sending and receiving token transfers. Integrators can manage these limits via their own governance processes to quickly adapt to on-chain activity. -Connect can be [fully customized](https://connect-in-style.wormhole.com/){target=\_blank} to choose the chains and assets you wish to support. You may also select different themes and colors to tailor Connect for your decentralized application. For details, see the [GitHub readme](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. +If a transfer is rate-limited on the source chain and queueing is enabled via `shouldQueue = true`, the transfer is placed into an outbound queue and can be released after the rate limit expires. -## Which functions or events does Connect rely on for NTT integration? +You can configure the following limits on every chain where NTT is deployed directly using the manager: -Connect relies on the NTT SDK for integration, with platform-specific implementations for Solana and EVM. The critical methods involved include initiate and redeem functions and rate capacity methods. These functions ensure Connect can handle token transfers and manage chain-rate limits. +- **Sending limit** - a single outbound limit for sending tokens from the chain +- **Per-chain receiving limits** - the maximum receiving limit, which can be configured on a per-chain basis. For example, allowing 100 tokens to be received from Ethereum but only 50 tokens to be received from Arbitrum -## Do integrators need to enable wallets like Phantom or Backpack in Wormhole Connect? +Rate limits are replenished every second over a fixed duration. While the default duration is 24 hours, the value is configurable at contract creation. Rate-limited transfers on the destination chain are added to an inbound queue with a similar release delay. -Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Wormhole Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. +## Update Rate Limits -## Which function should be modified to set priority fees for Solana transactions? +To configure or update the sending and receiving rate limits, follow these steps: -In [Wormhole Connect](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}, you can modify the priority fees for Solana transactions by updating the `computeBudget/index.ts` file. This file contains the logic for adjusting the compute unit limit and priority fees associated with Solana transactions. +1. **Locate the deployment file** - open the `deployment.json` file in your NTT project directory. This file contains the configuration for your deployed contracts -To control the priority fee applied to your transactions, you can modify the `feePercentile` and `minPriorityFee` parameters in the `addComputeBudget` and `determineComputeBudget` functions. +2. **Modify the limits section** - for each chain, locate the limits field and update the outbound and inbound values as needed -The relevant file can be found in the Connect codebase: [`computeBudget/index.ts`](https://github.com/wormhole-foundation/wormhole-connect/blob/62f1ba8ee5502ac6fd405680e6b3816c9aa54325/sdk/src/contexts/solana/utils/computeBudget/index.ts){target=\_blank}. + ```json + "limits": { + "outbound": "1000.000000000000000000", + "inbound": { + "Ethereum": "100.000000000000000000", + "Arbitrum": "50.000000000000000000" + } + } + ``` -## Is there a minimum amount for bridging with CCTP or the Connect SDK? + - **`outbound`** - sets the maximum tokens allowed to leave the chain + - **`inbound`** - configures per-chain receiving limits for tokens arriving from specific chains -There is no minimum amount for bridging via CCTP if the user covers the gas fees on both the source and destination chains. However, if the transfer is automatically relayed, a minimum amount is required to cover relay fees on the destination chain. The relay provider charges these fees at cost. +3. **Push the configuration** - use the NTT CLI to synchronize the updated configuration with the blockchain -Current relay fees: + ```bash + ntt push + ``` -- Ethereum L1: ~4.2 USDC -- Base, Optimism, Arbitrum, Avalanche: 0.3 USDC +4. **Verify the changes** - after pushing, confirm the new rate limits by checking the deployment status -Additional notes: + ```bash + ntt status + ``` -- **USDC to Solana** - Wormhole's native CCTP route does not currently support automatic relaying of USDC to Solana. However, you can transfer USDC to Solana using the [Mayan plugin](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} for the SDK. Mayan is a protocol that integrates Wormhole and CCTP to enable this functionality -- **Frontend integrations** - - **Connect** - A pre-built UI available via [@wormhole-foundation/wormhole-connect](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} - - **TypeScript SDK** - A lower-level integration option, available via [@wormhole-foundation/sdk](https://www.npmjs.com/package/@wormhole-foundation/sdk){target=\_blank}, allowing developers to build custom UIs +???- note "`deployment.json` example" + ```json + { + "network": "Testnet", + "chains": { + "Sepolia": { + "version": "1.1.0", + "mode": "burning", + "paused": false, + "owner": "0x0088DFAC40029f266e0FF62B82E47A07467A0345", + "manager": "0x5592809cf5352a882Ad5E9d435C6B7355B716357", + "token": "0x5CF5D6f366eEa7123BeECec1B7c44B2493569995", + "transceivers": { + "threshold": 1, + "wormhole": { + "address": "0x91D4E9629545129D427Fd416860696a9659AD6a1", + "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" + } + }, + "limits": { + "outbound": "184467440737.095516150000000000", + "inbound": { + "ArbitrumSepolia": "500.000000000000000000" + } + }, + "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" + } + } + } + ``` - !!!note - The TypeScript SDK was previously referred to as the "Connect SDK," but this naming has since been discontinued. +## Queuing Mechanism + +When a transfer exceeds the rate limit, it is held in a queue and can be released after the set rate limit duration has expired. The sending and receiving queuing behavior is as follows: + +- **Sending** - if an outbound transfer violates rate limits, users can either revert and try again later or queue their transfer. Users must return after the queue duration has expired to complete sending their transfer +- **Receiving** - if an inbound transfer violates rate limits, it is in a queue. Users or relayers must return after the queue duration has expired to complete receiving their transfer on the destination chain + +Queuing is configured dynamically during each transfer by passing the `shouldQueue` parameter to the [`transfer` function](https://github.com/wormhole-foundation/native-token-transfers/blob/5e7ceaef9a5e7eaa13e823a67c611dc684cc0c1d/evm/src/NttManager/NttManager.sol#L171-L182){target=\_blank} in the `NttManager` contract. + +## Cancel Flows + +If users bridge frequently between a given source chain and destination chain, the capacity could be exhausted quickly. Loss of capacity can leave other users rate-limited, potentially delaying their transfers. The outbound transfer cancels the inbound rate limit on the source chain to avoid unintentional delays. This allows for refilling the inbound rate limit by an amount equal to the outbound transfer amount and vice-versa, with the inbound transfer canceling the outbound rate limit on the destination chain and refilling the outbound rate limit with an amount. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/features/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/faqs/ --- BEGIN CONTENT --- --- -title: Features -description: Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. -categories: Connect, Transfer +title: Native Token Transfers FAQs +description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +categories: NTT, Transfer --- -## Feature Support Matrix {: #feature-support-matrix} +# Wormhole NTT FAQs -*Scroll down for details about each column.* +## Do you have an example of how cross-chain lending can be implemented using Wormhole? -| **Network** | **Token Bridge** | **Token Bridge Relayer** | **Circle CCTP** | **ETH Bridge** | **Gas Drop Off** | -|:-----------:|:----------------:|:------------------------:|:---------------:|:--------------:|:----------------:| -| Solana | ✅ | ✅ | ✅ | ❌ | ✅ | -| Ethereum | ✅ | ✅ | ✅ | ✅ | ✅ | -| BSC | ✅ | ✅ | ❌ | ✅ | ✅ | -| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | -| Avalanche | ✅ | ✅ | ✅ | ✅ | ✅ | -| Fantom | ✅ | ✅ | ❌ | ❌ | ✅ | -| Kaia | ✅ | ❌ | ❌ | ❌ | ❌ | -| Celo | ✅ | ✅ | ❌ | ❌ | ✅ | -| Moonbeam | ✅ | ✅ | ❌ | ❌ | ✅ | -| Injective | ✅ | ❌ | ❌ | ❌ | ❌ | -| Sui | ✅ | ✅ | ✅ | ❌ | ✅ | -| Aptos | ✅ | ❌ | ✅ | ❌ | ❌ | -| Arbitrum | ✅ | ✅ | ✅ | ✅ | ✅ | -| Optimism | ✅ | ✅ | ✅ | ✅ | ✅ | -| Base | ✅ | ✅ | ✅ | ✅ | ✅ | -| Sei | ✅ | ❌ | ❌ | ❌ | ❌ | -| Scroll | ✅ | ❌ | ❌ | ❌ | ❌ | -| Blast | ✅ | ❌ | ❌ | ❌ | ❌ | -| X Layer | ✅ | ❌ | ❌ | ❌ | ❌ | +Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. -## Feature Explanation {: #feature-explanation} +Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/products/messaging/overview/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. -### Token Bridge {: #token-bridge} +## What causes the "No protocols registered for Evm" error in Wormhole SDK? -Wormhole is best known for its Token Bridge transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. +This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. -This route appears if both of the following conditions are satisfied: +To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: - - Both the origin and destination chains support Token Bridge - - No non-Token Bridge routes are available for the selected token +```rust +import '@wormhole-foundation/sdk-evm-ntt'; +``` -### Token Bridge Relayer {: #token-bridge-relayer} +By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. -On the [routes](/docs/build/transfers/connect/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. +## How can I transfer ownership of NTT to a multisig? -Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. +Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. -This route appears if all of the following conditions are satisfied: +1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) +2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer +3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) -- Both the origin and destination chains support Token Bridge -- Both the origin and destination chains support Token Bridge relayer -- No non-Token Bridge routes are available for the selected token -- The relayer supports the selected token on the origin chain +For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. -### Circle CCTP {: #circle-cctp} +## How can I specify a custom RPC for NTT? -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. +To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. -This route appears if all of the following conditions are satisfied: +Below’s an example of how the `overrides.json` file should be structured: -- Both the origin and destination chains support Circle CCTP -- The selected token is native Circle-issued USDC +???- code "`overrides.json`" + ```json + { + "chains": { + "Bsc": { + "rpc": "http://127.0.0.1:8545" + }, + "Sepolia": { + "rpc": "http://127.0.0.1:8546" + }, + "Solana": { + "rpc": "http://127.0.0.1:8899" + } + } + } + ``` -### ETH Bridge {: #eth-bridge} +## How can I redeem tokens if NTT rate limits block them on the target chain? -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. +If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. -This route appears if all of the following conditions are satisfied: +To resolve this: -- Both the origin and destination chains support the ETH Bridge -- The selected token is native ETH, wstETH, or canonical wETH +1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed +2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain -### Gas Drop Off {: #gas-drop-off} +In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. -A relayer can drop off some gas tokens on the destination chain by swapping some of the assets transferred to the native gas token. This is useful if the user wishes to transfer assets to a chain where they don't already have gas. This way, they don't need to onboard into the ecosystem from a centralized exchange. +## What are the challenges of deploying NTT to non-EVM chains? -This route appears if all of the following conditions are satisfied: +NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. -- Both the origin and destination chains support gas drop off -- An automatic route is selected -- The relayer accepts the selected token to swap into the gas token ---- END CONTENT --- +## Does the NTT manager function as an escrow account for a hub chain? -Doc-Content: https://wormhole.com/docs/build/transfers/connect/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect -description: Wormhole Connect is a React widget offering an easy-to-use interface to facilitate multichain asset transfers via Wormhole directly in a web application. -categories: Connect, Transfer ---- +Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. -# Wormhole Connect +## Which functions or events does Connect rely on for NTT integration? -Wormhole Connect is a customizable widget that brings wrapped and native token cross-chain asset transfers into your dApp in as few as 3 lines of code. Connect is available as a React component or hosted version via CDN so you can easily configure any application to transfer tokens via Wormhole. +Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: -## Build with Connect +- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain +- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion -[timeline left(wormhole-docs/.snippets/text/build/transfers/connect/connect-timeline.json)] +These functions ensure Connect can handle token transfers and manage chain-rate limits. -## See It In Action +## How does the relayer contract determine which transceiver to call? -Wormhole Connect is deployed live in several production apps. Here are a few: +The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. -- [Portal Bridge](https://portalbridge.com/){target=\_blank} -- [Jupiter](https://jup.ag/onboard/cctp){target=\_blank} -- [Pancake Swap](https://bridge.pancakeswap.finance/wormhole){target=\_blank} +## How do I create a verifier or transceiver? -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} page to learn how to combine Connect with other Wormhole products, including Native Token Transfer (NTT). +To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. -## Next Steps +For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. -
+## Can I use Hetzner for the NTT deployment? -- :octicons-tools-16:{ .lg .middle} **Get Started Now** +No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. - --- +## How can I transfer tokens with NTT with an additional payload? - Follow this series of how-to guides to integrate Connect into your React dApp and configure options to fit your user's needs. +You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. - [:custom-arrow: Get started](/docs/build/transfers/connect/overview/#integrate-connect) +- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message +- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message -- :octicons-tools-16:{ .lg .middle } **Multichain Swap** +!!!Important + You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. - --- +## Why use NTT over xERC20? - This tutorial guides you step-by-step through integrating Connect into your React dApp to transfer tokens from Sui to Avalanche Fuji. This tutorial is readily adaptable to work with other [supported networks](/docs/build/start-building/supported-networks/){target=\_blank}. +Shortcomings of xERC20: +- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach +- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies +- **No access control** - there are no built-in access controls for managing token transfers securely +- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security +- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups - [:custom-arrow: Get started](/docs/tutorials/connect/react-dapp/) +While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. +## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? -- :octicons-tools-16:{ .lg .middle } **Connect FAQs** +To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. - --- +## Is there a way to use NTT tokens with chains that don't currently support NTT? - Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. +Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. For example: - [:custom-arrow: Visit FAQs](/docs/build/transfers/connect/faqs/) +- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) +- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism +- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT -- :octicons-tools-16:{ .lg .middle } **Supported Features by Chain** +This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. - --- +## How can I update my NTT CLI version? - Get a more detailed look at Wormhole Connect features with a breakdown of supported features by chain. +To update an existing NTT CLI installation, run the following command in your terminal: - [:custom-arrow: Supported Features](/docs/build/transfers/connect/features/) +```bash +ntt update +``` -
+NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. + +For local development, you can update your CLI version from a specific branch or install from a local path. + +To install from a specific branch, run: + +```bash +ntt update --branch foo +``` + +To install locally, run: +```bash +ntt update --path path/to/ntt/repo +``` + +Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/connect/overview/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/get-started/ --- BEGIN CONTENT --- --- -title: Overview -description: Explore Wormhole Connect, the React widget that allows you to offer an easy-to-use UI for cross-chain asset transfers via Wormhole in a web application. -categories: Connect, Transfer +title: Get Started with NTT +description: NTT enables cross-chain token movement without wrapping. Install the CLI, deploy test tokens, and scaffold a project to integrate NTT into your app. +categories: NTT, Transfer --- -# Wormhole Connect +# Get Started with NTT -## Introduction {: #introduction } +## Introduction -Wormhole Connect is a React widget that lets developers offer an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. Check out the [Wormhole Connect GitHub repository](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank}. +The [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview){target=\_blank} framework enables seamless cross-chain token movement without wrapping or liquidity pools. This guide shows you how to install the NTT CLI, which is used to configure and deploy native token contracts, and scaffold your first project for deployment on testnet or mainnet. -The [Wormhole TypeScript SDK](https://docs.wormhole.com/wormhole/reference/sdk-docs){target=\_blank} allows you to implement the same functionality as the Connect widget but in your own UI. Check out the docs for more information on using the SDK instead of Connect. +If you are looking for a no-code experience to deploy on mainnet, you can explore the [NTT Launchpad](https://ntt.wormhole.com){target=\_blank}. -## Features {: #features } +## Prerequisites -Wormhole Connect is easy to customize to suit your application's needs. You can specify technical details like supported assets and custom RPCs or forgo customization and have a full-featured widget. The widget UI is highly customizable, with extensive styling options available, including a user-friendly no code styling interface for those who prefer a more visual approach to design. The features of Wormhole Connect include: +Before you begin, make sure you have: -- Multiple ways to bridge assets ([routes](/docs/build/transfers/connect/routes/){target=\_blank}) -- Extensive ways to style the UI (including the [no code styling interface](https://connect-in-style.wormhole.com/){target=\_blank}) -- Ways to [configure](/docs/build/transfers/connect/configuration/){target=\_blank} what feature set to offer -- Ability to configure any token to bridge via Wormhole -- [Ability to drop off some gas](/docs/build/transfers/connect/features/){target=\_blank} at the destination +- [Node.js and npm installed](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} +- [Bun installed](https://bun.sh/){target=\_blank} +- A wallet private key with tokens on supported chains +- ERC-20 or SPL tokens already deployed on the source and destination chains -For more details about the features of Wormhole Connect and a breakdown of supported features by chain, be sure to check [the features page](/docs/build/transfers/connect/features/){target=\_blank}. +## Don’t Have a Token Yet? -## Integrate Connect {: #integrate-connect } +To use NTT, you must have a token already deployed on the source and destination chains. If you don’t have one, follow the quick guides below to deploy a basic test token. -### Import Directly into a React App {: #import-directly-into-a-react-app} +???- interface "Deploy an ERC-20 Token on EVM" + Use the [example NTT token repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} to deploy a basic ERC-20 token contract on testnet. -First, install the Wormhole Connect npm package. You can read more about the package by clicking on the following button: [![npm version](https://img.shields.io/npm/v/@wormhole-foundation/wormhole-connect.svg)](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank} + 1. **Install Foundry** - install the [Forge CLI](https://book.getfoundry.sh/getting-started/installation){target=\_blank} -```bash -npm i @wormhole-foundation/wormhole-connect -``` + 2. **Clone the repository** – fetch the example contract repository -Now you can import the React component: + ```bash + git clone https://github.com/wormhole-foundation/example-ntt-token.git + cd example-ntt-token + ``` + + 3. **Deploy the token contract** – deploy to testnet with your preferred name, symbol, minter, and owner addresses -```ts -import WormholeConnect from '@wormhole-foundation/wormhole-connect'; + ```bash + forge create --broadcast \ + --rpc-url INSERT_RPC_URL \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + src/PeerToken.sol:PeerToken \ + --constructor-args "INSERT_TOKEN_NAME" "INSERT_TOKEN_SYMBOL" INSERT_MINTER_ADDRESS INSERT_OWNER_ADDRESS + ``` -function App() { - return ; -} -``` + 4. **Mint tokens** – send tokens to your address -### Use Hosted Version via CDN {: #use-hosted-version-via-cdn} + ```bash + cast send INSERT_TOKEN_ADDRESS \ + "mint(address,uint256)" \ + INSERT_RECIPIENT_ADDRESS \ + INSERT_AMOUNT_IN_WEI \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + --rpc-url INSERT_RPC_URL + ``` -If you're not using React, you can still embed Connect on your website by using the hosted version. This uses pre-built packages (which include React) served from NPM by jsdelivr.net. + !!! note + This token uses 18 decimals by default. All minting values must be specified in `wei` (1 token = 10^18). -```ts title="v1.x" -import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; -// Existing DOM element where you want to mount Connect -const container = document.getElementById('bridge-container'); +???- interface "Create and Mint SPL Tokens" + This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. -wormholeConnectHosted(container); -``` + 1. **Generate a Solana key pair** - run the following command to create a new wallet: -For help migrating from Connect v0.x to v1.x, see the [v1 Migration](/docs/build/transfers/connect/upgrade/){target=\_blank} guide. + ```bash + solana-keygen grind --starts-with w:1 --ignore-case + ``` -???- code "v0.x" - Simply copy and paste the following into your HTML body, and replace the ```INSERT_WORMHOLE_CONNECT_VERSION``` in the links with the most recent production version of Wormhole Connect. You can check what the most recent version is on [NPM](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/latest){target=\_blank}. + 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: - ```html - -
- - - - ``` + ```bash + solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON + ``` - For example, for [0.3.13](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/0.3.13){target=\_blank}: + 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: - ```html - -
- - - - ``` + === "Mainnet" + ```bash + solana config set -um + ``` -It is important to periodically update your Wormhole Connect instance to the latest version, as there are frequent functionality and security releases. + === "Testnet" + ```bash + solana config set -ut + ``` -## Configuration {: #configuration} + === "Devnet" + ```bash + solana config set -ud + ``` -This is just an overview of what's possible. Check the [Configuration docs](/docs/build/transfers/connect/configuration/){target=\_blank} for details about all the configuration options. + 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: -The default configuration of Wormhole Connect may not be exactly what you're looking for. You may want to: + ```bash + solana airdrop 2 + solana balance + ``` - - Use custom styles - - Restrict the chains that you allow in your app - - Add support for your project's token, and eliminate tokens you don't want to reduce noise - - Configuring custom RPC URLs (This is highly recommended as default public RPCs are heavily throttled) - - Restrict the [routes](/docs/build/transfers/connect/routes/){target=\_blank} that are available + 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} -For additional information on the preceding options, check the [configuration options](/docs/build/transfers/connect/configuration/){target=\_blank} and customize your widget however you like. ---- END CONTENT --- + ```bash + cargo install spl-token-cli + ``` -Doc-Content: https://wormhole.com/docs/build/transfers/connect/routes/ ---- BEGIN CONTENT --- ---- -title: Routes -description: Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. -categories: Connect, Transfer ---- + 6. **Create a new SPL token** - initialize the token on Solana -## Routes Overview {: #routes-overview} + ```bash + spl-token create-token + ``` -This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/build/transfers/connect/configuration/){target=\_blank}. + 7. **Create a token account** - generate an account to hold the token -Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. + ```bash + spl-token create-account INSERT_TOKEN_ADDRESS + ``` -When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/build/transfers/connect/features/){target=\_blank} to see under which exact conditions the routes appear. + 8. **Mint tokens** - send 1000 tokens to the created account -## Token Bridge Routes {: #token-bridge-routes} + ```bash + spl-token mint INSERT_TOKEN_ADDRESS 1000 + ``` -The Token Bridge is Wormhole's best-known transfer method. It locks assets on the source chain and mints Wormhole-wrapped "IOU" tokens on the destination chain. To transfer the assets back, the Wormhole-wrapped tokens are burned, unlocking the tokens on their original chain. + !!! note + NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. -#### Manual Route {: #manual-route} +## Install NTT CLI -The manual route transfer method requires two transactions: one on the origin chain to lock the tokens (or burn the Wormhole-wrapped tokens) and one on the destination chain to mint the Wormhole-wrapped tokens (or unlock the original tokens). To offer this option, enable the `bridge` route in the configuration. +
-#### Automatic Route {: #automatic-route} +The NTT CLI is recommended to deploy and manage your cross-chain token configuration. -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically - for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `relay` route is enabled in the configuration. +1. Run the installation command in your terminal: -## CCTP Routes (USDC) {: #cctp-routes-usdc} - -[Circle](https://www.circle.com/en/){target=\_blank}, the issuer of USDC, provides a native way for native USDC to be transferred between [CCTP-enabled](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank} chains. Wormhole Connect can facilitate such transfers. + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` -Note that if native USDC is transferred from the CCTP-enabled chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native USDC. +2. Verify the NTT CLI is installed: -#### Manual Route {: #manual-route-cctp} + ```bash + ntt --version + ``` -This transfer method requires two transactions: one on the origin chain to burn the USDC and one on the destination chain to mint the USDC. The manual CCTP route relies on CCTP only and doesn't use Wormhole messaging in the background. Enable the `cctpManual` route in the configuration to offer this option. +## Initialize a New NTT Project -#### Automatic Route {: #automatic-route-cctp} +1. Once the CLI is installed, scaffold a new project by running: -Trustless relayers can execute the second transaction on the user's behalf. Therefore, the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. To offer this option, enable the `cctpRelay` route in the configuration. + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` -## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} +2. Initialize a new `deployment.json` file specifying the network: -[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/build/transfers/connect/configuration/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. + === "Mainnet" + ```bash + ntt init Mainnet + ``` -#### Manual Route {: #manual-route-ntt} + === "Testnet" + ```bash + ntt init Testnet + ``` -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To offer this option, enable the `nttManual` route in the configuration. + After initialization, the `deployment.json` file contains your NTT configuration and starts with the selected network. -#### Automatic Route {: #automatic-route-ntt} + === "Mainnet" + ```json + { + "network": "Mainnet", + "chains": {} + } + ``` -Trustless relayers can execute the second transaction on the user's behalf, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. Wormhole Connect automatically detects whether the relayer supports a token and will display the option if the `nttRelay` route is enabled in the configuration. + === "Testnet" + ```json + { + "network": "Testnet", + "chains": {} + } + ``` -## ETH Bridge Route for Native ETH and wstETH {: #eth-bridge-route-for-native-eth-and-wsteth} +In the deployment steps, you will add your supported chains, their token addresses, deployment modes, and any custom settings. -[Powered by Uniswap liquidity pools](https://github.com/wormhole-foundation/example-uniswap-liquidity-layer){target=\_blank}, this route can transfer native ETH or wstETH between certain EVMs without going through the native bridges. For example, you can transfer native ETH from Arbitrum to Optimism and end up with Optimism ETH all in one go. Supported chains are Ethereum, Arbitrum, Optimism, Base, Polygon (canonical wETH), BSC (canonical wETH), and Avalanche (canonical wETH). +## Next Steps -#### Automatic Route {: #automatic-route-eth} +You have scaffolded your NTT project and initialized the configuration file. Next, follow the appropriate guide below to configure your supported chains and deploy NTT contracts: -Only the relayed route is available due to the complexity of the transaction that needs to be executed at the destination. To offer this option, enable the `ethBridge` and/or `wstETHBridge` route in the configuration to provide this option. +- [Deploy to EVM](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank}: Deploy NTT on EVM-compatible chains. +- [Deploy to Solana](/docs/products/native-token-transfers/guides/deploy-to-solana/){target=\_blank}: Deploy NTT on Solana. +--- END CONTENT --- -## USDT Bridge Route {: #usdt-bridge-route} +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-evm/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers EVM Deployment +description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. +categories: NTT, Transfer +--- -Operating on the same technology as the ETH Bridge, this route can transfer USDT between certain EVMs without going through the native bridges. The resulting token will be the canonical USDT token on the destination instead of the Wormhole-wrapped variant. Supported chains are Ethereum, Polygon, Avalanche, Arbitrum, Optimism, BSC, and Base. +# Deploy Native Token Transfers (NTT) to EVM Chains -#### Automatic Route {: #automatic-route-usdt} +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of ERC-20 tokens on [supported EVM-compatible chains](/docs/products/reference/supported-networks/#ntt){target=\_blank} using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. -Only the relayed route is available due to the complexity of the transaction that needs to be executed on the destination. Enable the `usdtBridge` route in the configuration to offer this option. +This guide walks you through deploying NTT on EVM chains, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. -## tBTC Route {: #tbtc-route} +## Deploy Your Token and Ensure Compatibility -You can bridge [Threshold's Bitcoin](https://threshold.network/){target=\_blank} via this hybrid solution that combines the Token Bridge and Threshold's contracts. Native tBTC is first locked in the Wormhole Token Bridge, transferred to the destination in the form of Wormhole-wrapped tBTC, which is then immediately locked in Threshold's contract that mints native tBTC for it. The net result is that the user ends up with native tBTC on chains where this Threshold contract is deployed (e.g., Solana, Polygon, Arbitrum, Optimism, or Base). +If you still need to do so, deploy the token contract to the destination or spoke chains. -Note that if native tBTC is transferred out of these chains to any other outside of this list, the transfer will be routed through the Token Bridge, and the resulting asset will be a Wormhole-wrapped token instead of native tBTC. +### Requirements for Token Deployment -#### Manual Route {: #manual-route-tbtc} +Wormhole’s NTT framework supports two [deployment models](/docs/products/native-token-transfers/overview#deployment-models){target=\_blank}: burn-and-mint and hub-and-spoke. **Both require an ERC-20 token (new or existing).** -This transfer method requires two transactions: one on the origin chain to burn or lock the tokens and one on the destination chain to mint them. To provide this option, enable the `tbtc` route in the configuration. ---- END CONTENT --- +??? interface "Burn-and-Mint" -Doc-Content: https://wormhole.com/docs/build/transfers/connect/upgrade/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect v1.0 Migration Guide -description: Learn how to migrate to Wormhole Connect v1.0, with step-by-step guidance on updating your package and configuration. -categories: Connect, Transfer ---- + Tokens must implement the following non-standard ERC-20 functions: -# Wormhole Connect v1.0 Migration Guide + - `burn(uint256 amount)` + - `mint(address account, uint256 amount)` -## Overview + These functions aren't part of the standard ERC-20 interface. Refer to the [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} for all required functions, errors, and events. -The Wormhole Connect feature has been updated to **version 1.0**, introducing a modernized design and improved routing for faster native-to-native token transfers. This stable release comes with several breaking changes in how to configure the application, requiring minor updates to your integration. + ??? interface "`INttToken` Interface" + ```solidity + // SPDX-License-Identifier: Apache 2 +pragma solidity >=0.8.8 <0.9.0; -This guide will help you migrate to the new version in just a few simple steps. By following this migration guide, you'll learn how to: +interface INttToken { + /// @notice Error when the caller is not the minter. + /// @dev Selector 0x5fb5729e. + /// @param caller The caller of the function. + error CallerNotMinter(address caller); - - Update to the latest Connect package - - Apply configuration changes to the **`WormholeConnectConfig`** object - - Understand new routing capabilities and plugin options + /// @notice Error when the minter is the zero address. + /// @dev Selector 0x04a208c7. + error InvalidMinterZeroAddress(); -These updates ensure better performance and a smoother integration experience. + /// @notice Error when insufficient balance to burn the amount. + /// @dev Selector 0xcf479181. + /// @param balance The balance of the account. + /// @param amount The amount to burn. + error InsufficientBalance(uint256 balance, uint256 amount); -For complete documentation on the previous version of Wormhole Connect, please refer to the [Wormhole Connect guide](/docs/build/transfers/connect/){target=\_blank}. + /// @notice The minter has been changed. + /// @dev Topic0 + /// 0x0b5e7be615a67a819aff3f47c967d1535cead1b98db60fafdcbf22dcaa8fa5a9. + /// @param newMinter The new minter. + event NewMinter(address previousMinter, address newMinter); -## Update the Connect Package + // NOTE: the `mint` method is not present in the standard ERC20 interface. + function mint(address account, uint256 amount) external; -To begin the migration process, update the Wormhole Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. + // NOTE: the `setMinter` method is not present in the standard ERC20 interface. + function setMinter(address newMinter) external; -Run the following command in your terminal: + // NOTE: NttTokens in `burn` mode require the `burn` method to be present. + // This method is not present in the standard ERC20 interface, but is + // found in the `ERC20Burnable` interface. + function burn(uint256 amount) external; +} + ``` -```bash -npm install @wormhole-foundation/wormhole-connect@^1.0 -``` + You’ll also need to set mint authority to the relevant `NttManager` contract. Example deployment scripts are available in the [`example-ntt-token` GitHub repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank}. -This command installs the latest stable version of Wormhole Connect and prepares your environment for the new configuration changes. +??? interface "Hub-and-Spoke Mode" -## Update the `WormholeConnectConfig` Object + Tokens only need to be ERC-20 compliant. The hub chain serves as the source of truth for supply consistency, while only spoke chains need to support minting and burning. For example, if Ethereum is the hub and Polygon is a spoke: -In version 1.0, the `WormholeConnectConfig` object underwent several breaking changes. Most of these changes are minor and can be applied quickly. Below is a summary of the key changes, followed by detailed examples. + - Tokens are locked on Ethereum + - Tokens are minted or burned on Polygon -### Summary of Breaking Changes + This setup maintains a consistent total supply across all chains. -- Chain names are now capitalized: `solana` → `Solana` -- `env` renamed to `network` and is now capitalized: `mainnet` → `Mainnet` -- `networks` renamed to `chains`, with capitalized names -- `routes` updated to use route plugins -- `nttGroups` removed in favor of route plugin configuration -- `tokensConfig` updated, with a new key `wrappedTokens` added -- Many UI-related properties consolidated under a top-level `ui` key -- `customTheme` and `mode` were removed, replaced by a top-level `theme` property +## NTT Manager Deployment Parameters -These changes are explained in more detail below, with examples for easy reference. +This table compares the configuration parameters available when deploying the NTT Manager using the CLI versus a manual deployment with a Forge script. It highlights which options are configurable via each method, whether values are auto-detected or hardcoded, and includes additional comments to help guide deployment decisions. -### Capitalize Chain Names +|
Parameter
| Forge Script | CLI | Both | Comments | +|-------------------------|------------------------|-------------------------------------|--------|----------------------------------------------| +| `token` | Input | `--token
` | Yes | | +| `mode` | Input | `--mode ` | Yes | Key decision: hub-and-spoke or mint-and-burn | +| `wormhole` | Input | Auto-detected via SDK/`ChainContext` | Similar| | +| `wormholeRelayer` | Input | Auto-detected via on-chain query/SDK| Similar| | +| `specialRelayer` | Input | Not exposed | No | Take into consideration if using custom relaying. Not recommended | +| `decimals` | Input, overridable | Auto-detected via token contract, not overridable | Similar | | +| `wormholeChainId` | Queried from Wormhole contract | `--chain` (network param, mapped internally) | Yes | | +| `rateLimitDuration` | Hardcoded (`86400`) | Hardcoded (`86400`) | Yes | Rate limit duration. A day is normal but worth deciding | +| `shouldSkipRatelimiter` | Hardcoded (`false`) | Hardcoded (`false`) | Yes | If rate limit should be disabled (when the manager supports it) | +| `consistencyLevel` | Hardcoded (`202`) | Hardcoded (`202`) | Yes | `202` (finalized) is the standard — lower is not recommended | +| `gasLimit` | Hardcoded (`500000`) | Hardcoded (`500000`) | Yes | | +| `outboundLimit` | Computed | Auto-detected/Hardcoded | Similar| Relative to rate limit | -In version 1.0, chain names are now consistent with the `Chain` type from the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, and must be capitalized. This affects all config properties where a chain is referenced, including `rpcs`, `rest`, `graphql`, and `chains`. -=== "v0.x" +## Deploy NTT - ```typescript - const config: WormholeConnectConfig = { - rpcs: { - ethereum: 'INSERT_ETH_RPC_URL', - solana: 'INSERT_SOLANA_RPC_URL', - }, - }; - ``` -=== "v1.x" +Before deploying NTT contracts on EVM chains, you need to scaffold a project and initialize your deployment configuration. - ```typescript - const config: WormholeConnectConfig = { - rpcs: { - Ethereum: 'INSERT_ETH_RPC_URL', - Solana: 'INSERT_SOLANA_RPC_URL', - }, - }; - ``` +???- interface "Install the NTT CLI and Scaffold a New Project" + + Before proceeding, make sure you have the NTT CLI installed and a project initialized. -You can find the complete list of supported chain names in the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/fa4ba4bc349a7caada809f209090d79a3c5962fe/core/base/src/constants/chains.ts#L12-L66){target=\_blank}. +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): -### Rename `env` to `network` +1. Install the NTT CLI: -The `env` property has been renamed to `network`, with capitalized values. This change affects how you configure Testnet and Mainnet environments. + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` -=== "v0.x" + Verify installation: - ```typescript - const config: WormholeConnectConfig = { - env: 'testnet', - }; + ```bash + ntt --version ``` -=== "v1.x" - ```typescript - const config: WormholeConnectConfig = { - network: 'Testnet', - }; - ``` +2. Initialize a new NTT project: -If you don’t explicitly set the `network` value, Connect will default to `Mainnet`. + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` -```typescript -// Defaults to Mainnet -const config: WormholeConnectConfig = {}; -``` +3. Create the deployment config**: -For more information, refer to the [network constants list](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/networks.ts){target=\_blank}. + === "Mainnet" -### Rename `networks` to `chains` + ```bash + ntt init Mainnet + ``` -The `networks` property, which allowed whitelisting chains, is now renamed `chains`, and the chain names are capitalized. + === "Testnet" -=== "v0.x" + ```bash + ntt init Testnet + ``` - ```typescript - const config: WormholeConnectConfig = { - networks: ['solana', 'ethereum'], - }; - ``` -=== "v1.x" + This generates a `deployment.json` file where your deployment settings will be stored. - ```typescript - const config: WormholeConnectConfig = { - chains: ['Solana', 'Ethereum'], - }; - ``` +Once you've completed those steps, return here to proceed with adding your EVM chains and deploying contracts. -### Update `routes` to Use Route Plugins +Ensure you have set up your environment correctly: -The `routes` property in Wormhole Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. +```bash +export ETH_PRIVATE_KEY=INSERT_PRIVATE_KEY +``` -By default, if no `routes` property is set, Wormhole Connect will provide routes for two core protocols: +Add each chain you'll be deploying to. The following example demonstrates configuring NTT in burn-and-mint mode on Ethereum Sepolia and Arbitrum Sepolia: - - [Wormhole Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} - - [CCTP](/docs/learn/transfers/cctp/){target=\_blank} +```bash +# Set scanner API Keys as environment variables +export SEPOLIA_SCAN_API_KEY=INSERT_ETHERSCAN_SEPOLIA_API_KEY +export ARBITRUMSEPOLIA_SCAN_API_KEY=INSERT_ARBISCAN_SEPOLIA_API_KEY -For most use cases, integrators require more than the default routes. The new `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including both default and third-party routes. +# Add each chain +# The contracts will be automatically verified using the scanner API keys above +ntt add-chain Sepolia --latest --mode burning --token INSERT_YOUR_TOKEN_ADDRESS +ntt add-chain ArbitrumSepolia --latest --mode burning --token INSERT_YOUR_TOKEN_ADDRESS +``` -#### Available `route` Plugins +While not recommended, you can pass the `-skip-verify` flag to the `ntt add-chain` command if you want to skip contract verification. -The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: +The `ntt add-chain` command takes the following parameters: -???- tip "`route` Plugins" - - **`TokenBridgeRoute`** - manually redeemed Wormhole Token Bridge route - - **`AutomaticTokenBridgeRoute`** - automatically redeemed (relayed) Token Bridge route - - **`CCTPRoute`** - manually redeemed CCTP route - - **`AutomaticCCTPRoute`** - automatically redeemed (relayed) CCTP route - - **`DEFAULT_ROUTES`** - array containing the four preceding routes (TokenBridgeRoute, AutomaticTokenBridgeRoute, CCTPRoute, AutomaticCCTPRoute) - - **`nttAutomaticRoute(nttConfig)`** - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route - - **`nttManualRoute(nttConfig)`** - function that returns the manually-redeemed NTT route - - **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array - - **`MayanRoute`** - route that offers multiple Mayan protocols - - **`MayanRouteSWIFT`** - route for Mayan’s Swift protocol only - - **`MayanRouteMCTP`** - route for Mayan’s MCTP protocol only - - **`MayanRouteWH`** - route for Mayan’s original Wormhole transfer protocol +- Name of each chain +- Version of NTT to deploy (use `--latest` for the latest contract versions) +- Mode (either `burning` or `locking`) +- Your token contract address -In addition to these routes, developers can create custom routes for their own Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. +The NTT CLI prints detailed logs and transaction hashes, so you can see exactly what's happening under the hood. -For further details on the Route plugin interface, refer to the [Wormhole TypeScript SDK route code](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/route.ts){target=\_blank}. +## Configure NTT -Now that you know the available `route` plugins, let's explore some examples of configuring them. +The NTT CLI takes inspiration from [git](https://git-scm.com/){target=\_blank}. You can run: -#### Example: Offer Only CCTP Transfers +- `ntt status` - checks whether your `deployment.json` file is consistent with what is on-chain +- `ntt pull` - syncs your `deployment.json` file with the on-chain configuration and set up rate limits with the appropriate number of decimals, depending on the specific chain. For example: -To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: + For Solana, the limits are set with 9 decimal places: + ```json + "inbound": { + "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana + } + ``` -```typescript -import WormholeConnect, { - AutomaticCCTPRoute, - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; + For Sepolia (Ethereum Testnet), the limits are set with 18 decimal places: + ```json + "inbound": { + "Solana": "1000.000000000000000000" // inbound limit from Solana to Sepolia + } + ``` -const config: WormholeConnectConfig = { - routes: [AutomaticCCTPRoute], -}; + This initial configuration ensures that the rate limits are correctly represented for each chain's token precision + +- `ntt push` - syncs the on-chain configuration with local changes made to your `deployment.json` file -; -``` +After you deploy the NTT contracts, ensure that the deployment is properly configured and your local representation is consistent with the actual on-chain state by running `ntt status` and following the instructions shown on the screen. -#### Example: Offer All Default Routes and Third-Party Plugins +## Set Token Minter to NTT Manager -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +The final step in the deployment process is to set the NTT Manager as a minter of your token on all chains you have deployed to in `burning` mode. When performing a hub-and-spoke deployment, it is only necessary to set the NTT Manager as a minter of the token on each spoke chain. -```typescript -import WormholeConnect, { - DEFAULT_ROUTES, - nttRoutes, - MayanRouteSWIFT, - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +!!! note + The required NTT Manager address can be found in the `deployment.json` file. -import { myNttConfig } from './consts'; // Custom NTT configuration +- If you followed the [`INttToken`](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} interface, you can execute the `setMinter(address newMinter)` function + ```json + cast send $TOKEN_ADDRESS "setMinter(address)" $NTT_MANAGER_ADDRESS --private-key $ETH_PRIVATE_KEY --rpc-url $YOUR_RPC_URL + ``` -const config: WormholeConnectConfig = { - routes: [...DEFAULT_ROUTES, ...nttRoutes(myNttConfig), MayanRouteSWIFT], -}; +- If you have a custom process to manage token minters, you should now follow that process to add the corresponding NTT Manager as a minter -; -``` +By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. -This flexible plugin allows you to combine default routes (such as Token Bridge and CCTP) with third-party protocols, offering complete control over which routes are available in your application. +!!!important + To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} page. +--- END CONTENT --- -### Update the `tokensConfig` Structure +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/deploy-to-solana/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Solana Deployment +description: Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. +categories: NTT, Transfer +--- -In Wormhole Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. +# Deploy Native Token Transfers on Solana -Key Changes to `tokensConfig`: +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. - - **Capitalized chain names** - all chain names, like `ethereum`, must now be capitalized, such as `Ethereum`, to maintain consistency with the rest of the Wormhole SDK - - **`wrappedTokens`** - this new key replaces `foreignAssets` and defines the wrapped token addresses on foreign chains, making it easier to manage cross-chain transfers. It consolidates the wrapped token addresses into a cleaner structure. These addresses must be specified to enable token transfers to and from the foreign chain via token bridge routes - - **Simplified decimals** - instead of using a map of decimal values for different chains, you now only need to provide a single decimals value for the token's native chain +This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. -=== "v0.x" +## Prerequisites - In the old structure, the `foreignAssets` field defined the token’s presence on other chains, and `decimals` were mapped across multiple chains. +Before deploying NTT on Solana, ensure you have the following: - ```typescript - import WormholeConnect, { - WormholeConnectConfig, - } from '@wormhole-foundation/wormhole-connect'; +- [Rust](https://www.rust-lang.org/tools/install){target=\_blank} +- [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** +- [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** - const config: WormholeConnectConfig = { - tokensConfig: { - WETH: { - key: 'WETH', - symbol: 'WETH', - nativeChain: 'ethereum', - icon: Icon.ETH, - tokenId: { - chain: 'ethereum', - address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', - }, - coinGeckoId: 'ethereum', - color: '#62688F', - decimals: { Ethereum: 18, default: 8 }, - foreignAssets: { - Solana: { - address: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs', - decimals: 8, - }, - }, - }, - }, - }; - ``` -=== "v1.x" +Use the Solana and Anchor versions listed above to avoid compatibility issues while following this guide. - In v1.0, `foreignAssets` has been replaced with `wrappedTokens`, simplifying token transfers across chains by directly mapping wrapped token addresses. The `decimals` value is now a simple number representing the token’s decimals on its native chain. +## Overview of the Deployment Process - ```typescript - import WormholeConnect, { - WormholeConnectConfig, - } from '@wormhole-foundation/wormhole-connect'; +Deploying NTT with the CLI on Solana follows a structured process: - const config: WormholeConnectConfig = { - tokensConfig: { - WETH: { - key: 'WETH', - symbol: 'WETH', - nativeChain: 'Ethereum', // Chain name now capitalized - icon: Icon.ETH, - tokenId: { - chain: 'Ethereum', - address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', - }, - coinGeckoId: 'ethereum', - color: '#62688F', - decimals: 18, // Simplified decimals field - }, - }, - wrappedTokens: { - WETH: { - Solana: '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs', - /* additional chains */ - }, - }, - }; - ``` +1. **Choose your token setup**: -### Update NTT Configuration + - **Use an existing SPL token** - if your token is already deployed on Solana, you can skip token creation and move directly to the [Set Up NTT](#set-up-ntt) section + - **Create a new SPL token** - if you don't already have an SPL token deployed, you'll need to deploy and configure it on Solana before integrating with Wormhole's NTT -In Wormhole Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. + ???- interface "Create and Mint SPL Tokens" + This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. -Key changes: + 1. **Generate a Solana key pair** - run the following command to create a new wallet: - - **Removed `nttGroups`** - the `nttGroups` property has been removed from the configuration and is now passed as an argument to the `nttRoutes` function - - **Direct NTT route configuration** - NTT routes are now defined more explicitly, allowing for a more organized structure when specifying tokens, chains, and managers + ```bash + solana-keygen grind --starts-with w:1 --ignore-case + ``` -This change simplifies the configuration process by providing a cleaner, more flexible way to handle NTT routes across different chains. + 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: -=== "v0.x" + ```bash + solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON + ``` - In the previous version, `nttGroups` defined the NTT managers and transceivers for different tokens across multiple chains. + 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: - ```typescript - import WormholeConnect, { - nttRoutes, - WormholeConnectConfig, - } from '@wormhole-foundation/wormhole-connect'; - - const config: WormholeConnectConfig = { - nttGroups: { - Lido_wstETH: { - nttManagers: [ - { - chainName: 'ethereum', - address: '0xb948a93827d68a82F6513Ad178964Da487fe2BD9', - tokenKey: 'wstETH', - transceivers: [ - { - address: '0xA1ACC1e6edaB281Febd91E3515093F1DE81F25c0', - type: 'wormhole', - }, - ], - }, - { - chainName: 'bsc', - address: '0x6981F5621691CBfE3DdD524dE71076b79F0A0278', - tokenKey: 'wstETH', - transceivers: [ - { - address: '0xbe3F7e06872E0dF6CD7FF35B7aa4Bb1446DC9986', - type: 'wormhole', - }, - ], - }, - ], - }, - }, - }; - ``` -=== "v1.x" + === "Mainnet" + ```bash + solana config set -um + ``` - In v1.0, `nttGroups` has been removed, and the configuration is passed to the NTT route constructor as an argument. The tokens and corresponding transceivers are now clearly defined within the `nttRoutes` configuration. + === "Testnet" + ```bash + solana config set -ut + ``` - ```typescript - import WormholeConnect, { - nttRoutes, - WormholeConnectConfig, - } from '@wormhole-foundation/wormhole-connect'; + === "Devnet" + ```bash + solana config set -ud + ``` - const config: WormholeConnectConfig = { - routes: [ - ...nttRoutes({ - tokens: { - Lido_wstETH: [ - { - chain: 'Ethereum', - manager: '0xb948a93827d68a82F6513Ad178964Da487fe2BD9', - token: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', - transceiver: [ - { - address: '0xA1ACC1e6edaB281Febd91E3515093F1DE81F25c0', - type: 'wormhole', - }, - ], - }, - { - chain: 'Bsc', - manager: '0x6981F5621691CBfE3DdD524dE71076b79F0A0278', - token: '0x26c5e01524d2E6280A48F2c50fF6De7e52E9611C', - transceiver: [ - { - address: '0xbe3F7e06872E0dF6CD7FF35B7aa4Bb1446DC9986', - type: 'wormhole', - }, - ], - }, - ], - }, - }), - /* other routes */ - ], - }; - ``` + 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: - In this new structure, NTT routes are passed directly through the `nttRoutes` function, with the `token`, `chain`, `manager` and `transceiver` clearly defined for each supported asset. + ```bash + solana airdrop 2 + solana balance + ``` -### Update UI Configuration + 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} -In Wormhole Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. + ```bash + cargo install spl-token-cli + ``` -Key UI changes: + 6. **Create a new SPL token** - initialize the token on Solana - - **Consolidated UI properties** - many UI-related properties moved under a new top-level ui key for better organization - - **Removed `customTheme` and `mode`** - these properties have been removed in favor of a new top-level prop called `theme`, which simplifies theming and allows dynamic switching between themes + ```bash + spl-token create-token + ``` -#### UI Properties + 7. **Create a token account** - generate an account to hold the token -The following properties that were previously defined at the root level of the configuration are now part of the `ui` key: + ```bash + spl-token create-account INSERT_TOKEN_ADDRESS + ``` - - `explorer` → `ui.explorer` - specifies the explorer to use for viewing transactions - - `bridgeDefaults` → `ui.defaultInputs` - sets default input values for the bridge, such as the source and destination chains and token - - `pageHeader` → `ui.pageHeader` - sets the title and header for the page - - `menu` → `ui.menu` - defines the menu items displayed in the interface - - `searchTx` → `ui.searchTx` - configures the transaction search functionality - - `partnerLogo` → `ui.partnerLogo` - displays a partner's logo on the interface - - `walletConnectProjectId` → `ui.walletConnectProjectId` - integrates WalletConnect into the UI - - `showHamburgerMenu` → `ui.showHamburgerMenu` - enables or disables the hamburger menu for navigation + 8. **Mint tokens** - send 1000 tokens to the created account -Additionally, there are two new properties under `ui`: + ```bash + spl-token mint INSERT_TOKEN_ADDRESS 1000 + ``` - - **`ui.title`** - sets the title rendered in the top left corner of the UI. The default is "Wormhole Connect" - - **`ui.getHelpUrl`** - URL that Connect will render when an unknown error occurs, allowing users to seek help. This can link to a Discord server or any other support channel + !!! note + NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. -```typescript -import WormholeConnect, { - WormholeConnectConfig, -} from '@wormhole-foundation/wormhole-connect'; +2. **Choose your deployment model**: -const config: WormholeConnectConfig = { - ui: { - title: 'My Custom Bridge Example', - getHelpUrl: 'https://examplehelp.com/', - menu: [ - { - label: 'Support', - href: 'https://examplehelp.com/support', - target: '_blank', - order: 1, // Order of appearance in the menu - }, - { - label: 'About', - href: 'https://examplehelp.com/about', - target: '_blank', - order: 2, - }, - ], - showHamburgerMenu: false, - }, -}; -``` + - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required + - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program -#### UI Configuration +3. **Deploy and configure NTT** - use the NTT CLI to initialize and deploy the NTT program, specifying your SPL token and deployment mode -In the old structure, UI-related settings like `explorer` and `bridgeDefaults` were defined at the root level of the configuration. In version 1.0, these properties are now organized under the `ui` key, improving the configuration's readability and manageability. +![Solana NTT deployment diagram](/docs/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp) -=== "v0.x" +Following this process, your token will fully integrate with NTT, enabling seamless transfers between Solana and other chains. - ```typescript - const config: WormholeConnectConfig = { - bridgeDefaults: { - fromNetwork: 'solana', - toNetwork: 'ethereum', - tokenKey: 'USDC', - requiredNetwork: 'solana', - }, - showHamburgerMenu: true, - }; - ``` -=== "v1.x" +By default, NTT transfers to Solana require manual [relaying](/docs/protocol/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. - ```typescript - const config: WormholeConnectConfig = { - ui: { - defaultInputs: { - fromChain: 'Solana', // Chain names now capitalized - toChain: 'Ethereum', - tokenKey: 'USDC', - requiredChain: 'Solana', - }, - showHamburgerMenu: true, - }, - }; - ``` +## Set Up NTT -#### Remove `customTheme` and `mode` Properties +To integrate your token with NTT on Solana, you must initialize the deployment and configure its parameters. This process sets up the required contracts and may generate key pairs if they don't exist. These key pairs are used to sign transactions and authorize actions within the NTT deployment. -In version 1.0, the `customTheme` and `mode` properties, which were previously used to set themes, have been removed. They have been replaced by a new top-level prop called `theme`, which allows for more flexibility and dynamic updates to themes. +The [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: -Important details: +???- interface "Install the NTT CLI and Scaffold a New Project" - - The `theme` prop is not part of the `config` object and is passed separately to Wormhole Connect - - `config` cannot be modified after Connect has mounted, but the `theme` can be updated dynamically to support changes such as switching between light and dark modes or updating color schemes + Before proceeding, make sure you have the NTT CLI installed and a project initialized. -=== "v0.x" +Follow these steps (or see the [Get Started guide](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank}): - ```typescript - const config: WormholeConnectConfig = { - customTheme: { - primaryColor: '#4266f5', - secondaryColor: '#ff5733', - }, - mode: 'dark', - }; +1. Install the NTT CLI: - ; + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash ``` -=== "v1.x" - ```typescript - const theme: WormholeConnectTheme = { - mode: 'dark', // Can be dynamically changed - font: 'Arial', - button: { - primary: '#4266f5', - }, - }; + Verify installation: - ; + ```bash + ntt --version ``` -### Removed Configuration Properties +2. Initialize a new NTT project: -Several configuration properties have been removed in Wormhole Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` -Removed config keys: +3. Create the deployment config**: - - `cta` - - `cctpWarning` - - `pageSubHeader` - - `moreTokens` - - `moreChains` - - `ethBridgeMaxAmount` - - `wstETHBridgeMaxAmount` - - `customTheme` - - `mode` + === "Mainnet" -If your current setup includes any of these properties, you can safely remove them, as they are no longer supported in v1.0. + ```bash + ntt init Mainnet + ``` -## Use the CDN-Hosted Version of Wormhole Connect + === "Testnet" -For those using the CDN-hosted version of Wormhole Connect, the package's installation and integration have been updated. You must install the Connect package from npm and use the new `wormholeConnectHosted` utility function. + ```bash + ntt init Testnet + ``` -### Install and Integrate the Hosted Version + This generates a `deployment.json` file where your deployment settings will be stored. -1. Install the Connect package via npm: + !!! note + Testnet deployment settings work for both Solana Testnet and Devnet networks. - ```bash - npm install @wormhole-foundation/wormhole-connect@^1.0 - ``` +### Generate an NTT Program Key Pair -2. After installing the package, you can embed Wormhole Connect into your page by adding the following code: +Create a unique key pair for the NTT program: - ```typescript - import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; +```bash +solana-keygen grind --starts-with ntt:1 --ignore-case +``` - const container = document.getElementById('connect')!; +### Set Mint Authority - wormholeConnectHosted(container); +If you use burn-and-mint mode, follow these steps to enable the NTT program to mint tokens on Solana. This involves deriving the PDA as the token authority and updating the SPL token's minting permissions. + +If you want to use hub-and-spoke, skip this section and proceed to [Deploy and Configure NTT](#deploy-and-configure-ntt). + +Before updating the mint authority, you must create metadata for your SPL token. You can visit this repository to see an example of [how to create metadata for your SPL token](https://github.com/wormhole-foundation/demo-metaplex-metadata/blob/main/src/token-metadata.ts){target=\_blank}. + +Follow these steps to set the mint authority using the NTT CLI: + +1. **Derive the token authority** - generate the PDA, which will manage token minting + + ```bash + ntt solana token-authority INSERT_YOUR_NTT_PROGRAM_KEY_PAIR ``` -### Example: Custom Configuration for Hosted Version +2. **Set SPL token mint authority** - delegate minting control to the derived PDA -The `wormholeConnectHosted` function accepts two parameters: `config` and `theme`. This allows you to customize the routes and apply a theme directly within the hosted version. Here’s an example of how you can pass a custom configuration: + ```bash + spl-token authorize INSERT_TOKEN_ADDRESS mint INSERT_DERIVED_PDA + ``` -```typescript -import { - wormholeConnectHosted, - MayanRoute, -} from '@wormhole-foundation/wormhole-connect'; +## Deploy and Configure NTT -const container = document.getElementById('connect')!; +!!! warning + If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/products/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. -wormholeConnectHosted(container, { - config: { - routes: [MayanRoute], - eventHandler: (e) => { - console.log('Connect event', e); - }, - }, - theme: { - background: { - default: '#004547', - }, - }, -}); -``` -In this example, the `config` object defines the routes (in this case, using the Mayan route), while the `theme` object allows customization of the Connect interface (e.g., background color). ---- END CONTENT --- +After setting up your deployment, finalize the configuration and deploy the NTT program on Solana by following these steps: -Doc-Content: https://wormhole.com/docs/build/transfers/ ---- BEGIN CONTENT --- ---- -title: Multichain Transfers -description: This section guides you through using Wormhole products to securely and efficiently transfer assets and messages across multiple blockchains. ---- +1. **Deploy NTT to Solana** - run the appropriate command based on your deployment mode: -# Multichain Transfers + === "Burn-and-Mint" -Wormhole transfer products offer multiple asset transfer options to meet developer needs and use cases. These sections include guides to integrate and use Wormhole transfer products to securely and efficiently transfer assets and messages across multiple blockchains. + ```bash + ntt add-chain Solana --latest --mode burning --token INSERT_TOKEN_ADDRESS --payer INSERT_YOUR_KEYPAIR_JSON --program-key INSERT_YOUR_NTT_PROGRAM_KEYPAIR_JSON + ``` -Use the following links to jump directly to each Wormhole transfer product page or continue on for a feature-based product comparison. + === "Hub-and-Spoke" -- [**Connect**](/docs/build/transfers/connect/) - a pre-built bridging UI for cross-chain token transfers, requiring minimal setup -- [**Native Token Transfers (NTT)**](/docs/build/transfers/native-token-transfers/) - a mechanism to transfer native tokens cross-chain seamlessly without converting to a wrapped asset -- [**Token Bridge**](/docs/learn/transfers/token-bridge/) - a bridging solution that uses a lock and mint mechanism -- [**Settlement**](/docs/build/transfers/settlement/) - an intent protocol suite for fast multichain transfers, optimizing liquidity flows and interoperability without relying on traditional bridging methods + ```bash + ntt add-chain Solana --latest --mode locking --token INSERT_TOKEN_ADDRESS --payer INSERT_YOUR_KEYPAIR_JSON --program-key INSERT_YOUR_NTT_PROGRAM_KEYPAIR_JSON + ``` -## Products By Feature + You can optionally add `--solana-priority-fee` to the script to increase the priority fee in microlamports. The default is `50000`. -While all of these products handle token transfers, there are additional features to consider when selecting the best fit for your project needs. +2. **Verify deployment status** - after deployment, check if your `deployment.json` file matches the on-chain configuration using the following command: -
+ ```bash + ntt status + ``` -- :octicons-file-code-16:{ .lg .middle } **Message Payload** + If needed, sync your local configuration with the on-chain state: - --- + ```bash + ntt pull + ``` + +3. **Configure inbound and outbound rate limits** - by default, the inbound and outbound limits are set to `0` and must be updated before deployment. For EVM chains, values must be set using 18 decimals, while Solana uses nine decimals. - Send message payloads for social platforms, NFTs, and more with Token Bridge's lock and mint wrapped token mechanism. + Open your `deployment.json` file and adjust the values based on your use case: - [:custom-arrow: Discover Token Bridge](/docs/build/transfers/token-bridge/) + ```json + "inbound": { + "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana + }, + "outbound": { + "Sepolia": "1000.000000000" // outbound limit from Solana to Sepolia + } + ``` -- :octicons-file-code-16:{ .lg .middle } **Native Assets** +4. **Push the final deployment** - once rate limits are set, push the deployment to Solana using the specified key pair to cover gas fees - --- + ```bash + ntt push --payer INSERT_YOUR_KEYPAIR_JSON + ``` - Eliminate the need for wrapped tokens and issue native multichain assets with Native Token Transfers (NTT). +### Recovering Rent for Failed Solana Deployments - [:custom-arrow: Discover Native Token Transfers](/docs/build/transfers/native-token-transfers/) +Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked in deployment buffer accounts that persist after interruptions. To recover these funds, refer to the [Solana program deployment guide](https://solana.com/docs/programs/deploying#program-buffer-accounts){target=\_blank} for instructions on identifying and closing these buffer accounts. +## Where to Go Next -- :octicons-file-code-16:{ .lg .middle } **Speed at Scale** +
- --- +- :octicons-globe-16:{ .lg .middle } **Deploy NTT on EVM Chains** - Unleash institutional-scale digital asset settlement with Wormhole Settlement's intent-based asset transfers and liquidity layer. + --- + + After deploying NTT on Solana, deploy and integrate it on EVM chains to enable seamless multichain transfers. - [:custom-arrow: Discover Settlement](/docs/build/transfers/settlement/) + [:custom-arrow: Deploy NTT on EVM Chains](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank} -- :octicons-gear-16:{ .lg .middle } **Plug-and-Play UI** +- :octicons-tools-16:{ .lg .middle } **Test Your Deployment** --- - Add Wormhole's bridge UI to your dApp, no smart contract development required, with Connect. + Follow the NTT Post Deployment Guide for integration examples and testing instructions. - [:custom-arrow: Discover Connect](/docs/build/transfers/connect/) + [:custom-arrow: Test Your NTT deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} -
+- :octicons-tools-16:{ .lg .middle } **Add NTT to Your dApp** -## Additional Resources + --- -
+ Configure Wormhole Connect, a plug-and-play bridging UI, to enable multichain transfers for your token. + + [:custom-arrow: Use Connect to Integrate NTT](/docs/products/connect/overview/){target=\_blank} -- :octicons-tools-16:{ .lg .middle } **Product Comparison** +- :octicons-question-16:{ .lg .middle } **View FAQs** --- - Compare Wormhole's cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. + Find answers to common questions about NTT. - [:custom-arrow: Compare Products](/docs/build/start-building/products/) + [:custom-arrow: View FAQs](/docs/products/native-token-transfers/faqs){target=\_blank} -- :octicons-book-16:{ .lg .middle } **Use Cases** +- :octicons-question-16:{ .lg .middle } **View FAQs** --- - Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. - - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) + Find answers to common questions about NTT. + [:custom-arrow: View FAQs](/docs/build/transfers/native-token-transfers/faqs){target=\_blank}
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/cli-commands/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/evm-launchpad/ --- BEGIN CONTENT --- --- -title: NTT CLI Commands -description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +title: Deploy Native Token Transfers with Launchpad +description: Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. categories: NTT, Transfer --- -# NTT CLI Commands +# Deploy Native Token Transfers with Launchpad ## Introduction -The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. +The [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT across multiple blockchains. -If you haven't installed the NTT CLI yet, follow the [NTT Installation Guide](/docs/build/transfers/native-token-transfers/deployment-process/installation/#installation){target=\_blank} to set it up before proceeding. +Instead of manually deploying contracts on each chain, configuring relayers, and managing cross-chain communication, you can quickly launch or expand tokens with just a few clicks. -## Table of Commands +The Launchpad automates deployment, reducing complexity and saving time. -The following table lists the available NTT CLI commands, descriptions, and examples. +This guide covers: -To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. + - Launching a new cross-chain token + - Expanding an existing token for NTT + - Managing tokens via the dashboard and settings -### General Commands +## Prerequisites -| Command | Description | Examples | -|-----------------------------------------|-------------------------------------------------------|--------------------------| -| `ntt update` | update the NTT CLI | `ntt update` | -| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | -| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest`| -| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0`| -| `ntt clone
` | initialize a deployment file from an existing contract| `ntt clone Mainnet Solana Sol5678...`| -| `ntt init ` | initialize a deployment file | `ntt init devnet` | -| `ntt pull` | pull the remote configuration | `ntt pull` | -| `ntt push` | push the local configuration | `ntt push` | -| `ntt status` | check the status of the deployment | `ntt status` | + - An EVM-compatible wallet (e.g., [MetaMask](https://metamask.io/){target=\_blank}, [Phantom](https://phantom.com/){target=\_blank}, etc.) + - Minimum ETH (or equivalent) for gas fees per deployment -### Configuration Commands +## Supported Blockchains -| Command | Description | Examples | -|---------------------------------------------|----------------------------------------|-------------------------------------| -| `ntt config set-chain `| set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key`| -| `ntt config unset-chain ` | unset a configuration value for a chain| `ntt config unset-chain Ethereum scan_api_key`| -| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key`| +The NTT Launchpad currently supports deployments on the following mainnet chains: -### Solana Commands + - Ethereum + - Arbitrum One + - Base + - Berachain + - Blast + - BNB Smart Chain + - Ink + - Optimism Mainnet + - Polygon -| Command | Description | Examples | -|-----------------------------------------------|---------------------------------------------------------|------------------| -| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json`| -| `ntt solana token-authority ` | print the token authority address for a given program ID| `ntt solana token-authority Sol1234...`| -| `ntt solana ata `| print the token authority address for a given program ID| `ntt solana ata Mint123... Owner123... token22`| +## Choose Your Path -## Where to Go Next +Once ready, choose an option to proceed: -
+ - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token): Deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains. + - [**Expand Your Existing Token**](#expand-your-existing-token): If you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract. +## Launch a Cross-Chain Token -- :octicons-gear-16:{ .lg .middle } **Configure NTT** +Deploy a new NTT-compatible token that can be transferred across multiple chains. This process sets up your token on a home network and deploys it to additional blockchains. Follow the below steps to get started: - --- +1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) + +2. Select **Launch a Cross-Chain Token** - [:custom-arrow: Configure your NTT deployment](/docs/build/transfers/native-token-transfers/configuration/) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp) -- :octicons-question-16:{ .lg .middle } **NTT FAQs** +3. Set the token details: + 1. Select the **home network** from the dropdown menu + 2. Enter the **name** for the token + 3. Enter the **symbol** of the token + 4. Provide the **initial supply** + 5. To the token details, click **Next** - --- + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp) - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +4. Select the deployment chains: + 1. The home network where your token will be deployed will be populated (e.g., Optimism) + 2. Choose any additional chains to deploy your token to (e.g., Base) + 3. To continue, click **Next** - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp) -
---- END CONTENT --- +5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/access-control/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Access Control -description: Learn about the owner and pauser access roles for the NTT manager contract, which can be used to pause and un-pause token transfers. -categories: NTT, Transfer ---- + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) -## Owner and Pauser Roles +6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet -Pausing the Native Toke Transfer (NTT) Manager Contract will disallow initiating new token transfers. While the contract is paused, in-flight transfers can still be redeemed (subject to rate limits if configured). + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) -NTT can be paused on a particular chain by updating the `paused` parameter on the deployment to `true` via the NTT CLI, then performing `ntt push` to sync the local configuration with the on-chain deployment. +7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step -- **Owner** - full control over NTT contracts, can perform administrative functions. Has the ability to un-pause contracts if they have been paused -- **Pauser** - can pause NTT contracts to halt token transfers temporarily. This role is crucial for responding quickly to adverse events without a prolonged governance process. Cannot un-pause contracts +8. Once both deployments are completed, proceed to the [**Dashboard**](#explore-the-launchpad-dashboard) to manage your token. -You may verify the current owner, pauser, and paused status of the NTT Manager contract on the `deployment.json` file in your NTT project directory. +## Expand Your Existing Token -```json -{ - "network": "Testnet", - "chains": { - "Sepolia": { - "version": "1.1.0", - "mode": "burning", - "paused": true, // set to true to pause the contract - "owner": "0x0088DFAC40029f266e0FF62B82E47A07467A0345", - "manager": "0x5592809cf5352a882Ad5E9d435C6B7355B716357", - //... - "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" - } - } -} -``` +Expand an existing token to support NTT across multiple chains. This process integrates your deployed token with NTT without modifying its original contract. Follow the steps below to get started: -!!! note - While the `Pauser` can pause contracts, the ability to un-pause contracts is callable only by the `Owner`. +1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** -The `Owner` and the `Pauser` addresses can each pause the contract. Since the contract `Owner` address is typically a multisig or a more complex DAO governance contract, and pausing the contract only affects the availability of token transfers, protocols can choose to set the `Pauser` address to be a different address. Creating a separate `Pauser` helps protocols respond quickly to potential risks without going through a drawn-out process. + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) -Consider separating `Owner` and `Pauser` roles for your multichain deployment. `Owner` and `Pauser` roles are defined directly on the `NttManager` contract. ---- END CONTENT --- +2. Select **Expand Your Existing Token** -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers (NTT) - Configuration -description: This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -categories: NTT, Transfer ---- + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp) -# Configure Native Token Transfers (NTT) +3. Enter the token details: + 1. Choose the home network where your token is already deployed (e.g., Optimism) + 2. Choose any additional chains to deploy your token to (e.g., Base) + 3. To continue, click **Next** -## Get Started + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp) -This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. +4. Select the chains to deploy your token to: + 1. The home network where your token is already deployed will be populated (e.g., Optimism) + 2. Choose any additional chains to deploy your token to (e.g., Base) + 1. Click **Next** -
+ ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp) -- :octicons-clock-16:{ .lg .middle } **Rate Limiting** +5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - --- + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) - Discover options for configuring rate limits and how queueing effects transaction flow. +6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - [:custom-arrow: Explore rate limit options](/docs/build/transfers/native-token-transfers/configuration/rate-limiting/) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) -- :octicons-unlock-16:{ .lg .middle } **Access Control** +7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step - --- +8. Now that your token has been deployed on multiple chains click [**Dashboard**](#explore-the-launchpad-dashboard) to review its details - Learn more about access control, including why you should consider setting a separate Pauser address as part of your development security plan. +## Explore the Launchpad Dashboard - [:custom-arrow: Explore access control roles](/docs/build/transfers/native-token-transfers/configuration/access-control/) +To access the **Dashboard** from the [Launchpad home page](https://ntt.wormhole.com/){target=\_blank}, click on **Manage Deployment**. Here, you can view deployment status, monitor supply across chains, and configure transfer settings. -
---- END CONTENT --- +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp) -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/configuration/rate-limiting/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Rate Limiting -description: Learn about rate limits in Wormhole NTT by configuring send/receive limits, queuing, and canceling flows to manage multichain token transfers efficiently. -categories: NTT, Transfer ---- +The dashboard provides a high-level view of your token across all deployed chains, including: -## Introduction + - Token addresses for each chain + - Supply distribution visualization + - List of deployed chains, including inbound and outbound transfer limits, which can be modified in [**Settings**](#settings) -The Native Token Transfer (NTT) framework provides configurable per-chain rate limits for sending and receiving token transfers. Integrators can manage these limits via their own governance processes to quickly adapt to on-chain activity. +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp) -If a transfer is rate-limited on the source chain and queueing is enabled via `shouldQueue = true`, the transfer is placed into an outbound queue and can be released after the rate limit expires. +## Settings -You can configure the following limits on every chain where NTT is deployed directly using the manager: +The **Settings** page allows you to configure security parameters, role management, and transfer limits for your deployed token. You can switch between chains to manage these settings independently for each deployment. -- **Sending limit** - a single outbound limit for sending tokens from the chain -- **Per-chain receiving limits** - the maximum receiving limit, which can be configured on a per-chain basis. For example, allowing 100 tokens to be received from Ethereum but only 50 tokens to be received from Arbitrum +### Chain Management -Rate limits are replenished every second over a fixed duration. While the default duration is 24 hours, the value is configurable at contract creation. Rate-limited transfers on the destination chain are added to an inbound queue with a similar release delay. +Use the drop-down menu at the top to select the chain you want to configure. The available options correspond to the chains where your token has already been deployed. Once selected, the page displays token details specific to that chain. -## Update Rate Limits +From this section, you can also: -To configure or update the sending and receiving rate limits, follow these steps: + - **Pause the token**: Temporarily turn off transfers on the selected chain. + - **Deploy to a new chain**: Expand your token by deploying it to an additional chain. -1. **Locate the deployment file** - open the `deployment.json` file in your NTT project directory. This file contains the configuration for your deployed contracts +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp) -2. **Modify the limits section** - for each chain, locate the limits field and update the outbound and inbound values as needed +### Role Management - ```json - "limits": { - "outbound": "1000.000000000000000000", - "inbound": { - "Ethereum": "100.000000000000000000", - "Arbitrum": "50.000000000000000000" - } - } - ``` +This section displays key [roles](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. - - **`outbound`** - sets the maximum tokens allowed to leave the chain - - **`inbound`** - configures per-chain receiving limits for tokens arriving from specific chains + - **Manager’s Owner**: The owner through the `NTTOwner` proxy. + - **Pauser**: The address authorized to pause transfers. -3. **Push the configuration** - use the NTT CLI to synchronize the updated configuration with the blockchain +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp) - ```bash - ntt push - ``` +### Security Threshold -4. **Verify the changes** - after pushing, confirm the new rate limits by checking the deployment status +Determine and update how transceivers interact with the token. [Transceivers](/docs/products/native-token-transfers/concepts/architecture/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. - ```bash - ntt status - ``` +A higher transceiver threshold increases security by requiring more approvals before processing a transfer, but it may also slow down transactions. A lower threshold allows faster transfers but reduces redundancy in message verification. -???- note "`deployment.json` example" - ```json - { - "network": "Testnet", - "chains": { - "Sepolia": { - "version": "1.1.0", - "mode": "burning", - "paused": false, - "owner": "0x0088DFAC40029f266e0FF62B82E47A07467A0345", - "manager": "0x5592809cf5352a882Ad5E9d435C6B7355B716357", - "token": "0x5CF5D6f366eEa7123BeECec1B7c44B2493569995", - "transceivers": { - "threshold": 1, - "wormhole": { - "address": "0x91D4E9629545129D427Fd416860696a9659AD6a1", - "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" - } - }, - "limits": { - "outbound": "184467440737.095516150000000000", - "inbound": { - "ArbitrumSepolia": "500.000000000000000000" - } - }, - "pauser": "0x0088DFAC40029f266e0FF62B82E47A07467A0345" - } - } - } - ``` + - **Registered Transceivers**: Displays the number of registered transceivers and their addresses. + - **Transceivers Threshold**: A configurable value that must be less than or equal to the number of transceivers. -## Queuing Mechanism +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp) -When a transfer exceeds the rate limit, it is held in a queue and can be released after the set rate limit duration has expired. The sending and receiving queuing behavior is as follows: +### Peer Chains Limits -- **Sending** - if an outbound transfer violates rate limits, users can either revert and try again later or queue their transfer. Users must return after the queue duration has expired to complete sending their transfer -- **Receiving** - if an inbound transfer violates rate limits, it is in a queue. Users or relayers must return after the queue duration has expired to complete receiving their transfer on the destination chain +Define the transfer restrictions for each connected network. You can adjust: -Queuing is configured dynamically during each transfer by passing the `shouldQueue` parameter to the [`transfer` function](https://github.com/wormhole-foundation/native-token-transfers/blob/5e7ceaef9a5e7eaa13e823a67c611dc684cc0c1d/evm/src/NttManager/NttManager.sol#L171-L182){target=\_blank} in the `NttManager` contract. + - **Sending Limits**: The maximum amount of tokens that can be sent from the home chain. + - **Receiving Limits**: The maximum amount of tokens that can be received for each of the supported peer chains. -## Cancel Flows +Enter a new value to adjust limits and click **Update**. The changes will take effect immediately. -If users bridge frequently between a given source chain and destination chain, the capacity could be exhausted quickly. Loss of capacity can leave other users rate-limited, potentially delaying their transfers. The outbound transfer cancels the inbound rate limit on the source chain to avoid unintentional delays. This allows for refilling the inbound rate limit by an amount equal to the outbound transfer amount and vice-versa, with the inbound transfer canceling the outbound rate limit on the destination chain and refilling the outbound rate limit with an amount. +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp) --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/ +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/post-deployment/ --- BEGIN CONTENT --- --- -title: Native Token Transfers EVM Deployment -description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. +title: Native Token Transfers Post Deployment +description: Learn post-deployment guidelines for optimizing Wormhole NTT, which include testing, security, frontend integration, ecosystem coordination, and monitoring. categories: NTT, Transfer --- -# Native Token Transfers (NTT) EVM Development +# Native Token Transfers Post Deployment -## Deploy Your Token and Ensure Compatibility +To offer the best user experience and ensure the most robust deployment, Wormhole contributors recommend the following after you have deployed Native Token Transfers (NTT): -If you still need to do so, deploy the token contract to the destination or spoke chains. +- Implement a robust testing plan for your multichain token before launching +- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} for more details on ownership and rate limits +- Consider a streamlined, customizable frontend such as [Connect](/docs/products/connect/overview/){target=\_blank} for an optimized user experience +- Alternatively, the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} allows for a direct integration into your infrastructure +- Ensure ecosystem actors such as block explorers, automated security tools (such as BlockAid and Blowfish), and wallets (such as MetaMask, Backpack, and Phantom) are aware of your multichain deployment and that it is labeled appropriately +- Monitor and maintain your multichain deployment -### Requirements for Token Deployment +## Manual Relaying for Solana Transfers -Wormhole’s NTT is an open framework that supports various deployment modes. The NTT CLI currently supports two deployment modes: burn-and-mint and hub-and-spoke. These modes differ in how tokens are managed across chains. +By default, NTT transfers to Solana require manual relaying, meaning that after initiating a cross-chain transfer, the recipient must submit an on-chain transaction to claim the tokens. -#### Burn-and-Mint Mode +This step ensures that tokens are properly minted or unlocked on Solana and prevents unauthorized claims. -Tokens integrated with `NttManager` in `burning` mode require the following two functions to be present: +## Post-Deployment Settings -- `burn(uint256 amount)` -- `mint(address account, uint256 amount)` +The following table outlines post-deployment settings available on the NTT Manager contract. These allow you to update roles, pause activity, and adjust transfer limits—useful for upgrades, incident response, or protocol tuning after initial deployment. -These functions aren't part of the standard ERC-20 interface. The [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} documents the required functions and convenience methods, errors, and events. +| Setting | Effect | +|-------------------------|------------------------------------------| +| `pause` | Pauses the manager | +| `unpause` | Unpauses the manager | +| `setOwner` | Changes the manager owner | +| `setPauser` | Changes the pauser role | +| `setOutboundLimit` | Sets outbound transfer limit | +| `setInboundLimit` | Sets inbound transfer limit (per chain) | +| `setTransceiverPauser ` | Changes pauser for a transceiver | -??? code "View the complete `INttToken` Interface`" - ```solidity - // SPDX-License-Identifier: Apache 2 -pragma solidity >=0.8.8 <0.9.0; +## Where to Go Next -interface INttToken { - /// @notice Error when the caller is not the minter. - /// @dev Selector 0x5fb5729e. - /// @param caller The caller of the function. - error CallerNotMinter(address caller); +
- /// @notice Error when the minter is the zero address. - /// @dev Selector 0x04a208c7. - error InvalidMinterZeroAddress(); +- :octicons-code-16:{ .lg .middle } **Wormhole NTT Connect Demo** - /// @notice Error when insufficient balance to burn the amount. - /// @dev Selector 0xcf479181. - /// @param balance The balance of the account. - /// @param amount The amount to burn. - error InsufficientBalance(uint256 balance, uint256 amount); + --- - /// @notice The minter has been changed. - /// @dev Topic0 - /// 0x0b5e7be615a67a819aff3f47c967d1535cead1b98db60fafdcbf22dcaa8fa5a9. - /// @param newMinter The new minter. - event NewMinter(address previousMinter, address newMinter); + Check out an example project that uses a Vite-React TypeScript application and integrates it with Connect, a customizable widget for cross-chain asset transfers. - // NOTE: the `mint` method is not present in the standard ERC20 interface. - function mint(address account, uint256 amount) external; + [:custom-arrow: Explore the NTT Connect demo](https://github.com/wormhole-foundation/demo-ntt-connect) - // NOTE: the `setMinter` method is not present in the standard ERC20 interface. - function setMinter(address newMinter) external; +- :octicons-code-16:{ .lg .middle } **Wormhole NTT TypeScript SDK Demo** - // NOTE: NttTokens in `burn` mode require the `burn` method to be present. - // This method is not present in the standard ERC20 interface, but is - // found in the `ERC20Burnable` interface. - function burn(uint256 amount) external; -} - ``` + --- -Later, you set mint authority to the corresponding `NttManager` contract. You can also follow the scripts in the [example NTT token](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} repository to deploy a token contract. + Reference an example project that uses the Wormhole TypeScript SDK to facilitate token transfers between different blockchain networks after deploying the NTT framework. -#### Hub-and-Spoke Mode + [:custom-arrow: Explore the NTT TypeScript SDK demo](https://github.com/wormhole-foundation/demo-ntt-ts-sdk) -A central hub chain (e.g., Ethereum) manages the total token supply in hub-and-spoke mode. Other chains (spokes) mint or burn tokens during cross-chain transfers, ensuring consistency with the locked tokens on the hub chain. +
+--- END CONTENT --- - - **Hub chain** - tokens are locked on the hub chain when transferring to spoke chains - - **Spoke chains** - tokens are native to the spoke chains and are either minted or burned during cross-chain transfers +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/guides/troubleshoot/ +--- BEGIN CONTENT --- +--- +title: Troubleshooting NTT Deployment +description: Resolve common issues in NTT deployment with this troubleshooting guide covering Solana, EVM, mint authority, decimals, and rate limits. +categories: NTT, Transfer +--- -!!! note - The only requirement for using the NTT framework is an ERC20 token, which can be newly deployed or existing. Steps like setting mint authority apply only to spoke chains. +# Troubleshoot Your NTT Deployment -For example, when transferring tokens from Ethereum (hub) to Polygon (spoke), the NTT Manager locks tokens on Ethereum, and the corresponding amount is minted on Polygon. Similarly, transferring tokens back from Polygon to Ethereum burns the tokens on Polygon and unlocks the equivalent tokens on Ethereum. +If you encounter issues during the NTT deployment process, check the following common points: -This process ensures that the total token supply remains consistent across all chains, with the hub chain acting as the source of truth. +- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/products/native-token-transfers/guides/deploy-to-solana/#install-dependencies){target=\_blank} + - [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** + - [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** +- **Token compliance on EVM** - verify that your token is an ERC20 token on the EVM chain +- **Mint authority transfer** + - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/products/native-token-transfers/guides/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section + - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/products/native-token-transfers/guides/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details +- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/products/native-token-transfers/guides/deploy-to-solana/#configure-ntt){target=\_blank} section +- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/products/native-token-transfers/guides/deploy-to-evm/#configure-ntt){target=\_blank} +- **Docker environment based on Ubuntu 20.04 with all dependencies required for Wormhole NTT CLI development** - run `docker compose up -d` to start the container in your terminal from the directory containing the `docker-compose.yml` file -For more detailed information, see the [Deployment Models](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank} page. + ???- interface "Dockerfile" -### Key Differences Between Modes + ```Dockerfile + FROM ubuntu:20.04 + # Set environment variables to prevent interactive prompts during installation + ENV DEBIAN_FRONTEND=noninteractive - - **Burn-and-mint** - tokens must implement custom `mint` and `burn` functions, allowing each chain to manage token issuance independently - - **Hub-and-spoke** - tokens only need to be ERC20 compliant, with the hub chain acting as the source of truth for supply consistency + # Update and install necessary dependencies + RUN apt-get update && apt-get install -y \ + curl \ + wget \ + git \ + build-essential \ + libssl-dev \ + libudev-dev \ + pkg-config \ + python3 \ + python3-pip \ + software-properties-common \ + ca-certificates \ + unzip \ + clang \ + cmake \ + protobuf-compiler \ + && apt-get clean && rm -rf /var/lib/apt/lists/* -## Deploy NTT + # Install Rust + RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + ENV PATH="/root/.cargo/bin:$PATH" -Create a new NTT project: + # Install Solana CLI ({{ntt.solana_cli_version}}) + RUN sh -c "$(curl -sSfL https://release.solana.com/{{ntt.solana_cli_version}}/install)" + ENV PATH="/root/.local/share/solana/install/active_release/bin:$PATH" -```bash -ntt new my-ntt-deployment -cd my-ntt-deployment -``` + # Install Anchor using avm + RUN cargo install --git https://github.com/coral-xyz/anchor avm --locked --force \ + && avm install 0.29.0 \ + && avm use 0.29.0 + ENV PATH="/root/.avm/bin:$PATH" -Initialize a new `deployment.json` file specifying the network: -=== "Testnet" + ENV NVM_DIR=/root/.nvm + RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \ + && . "$NVM_DIR/nvm.sh" \ + && nvm install 22 \ + && nvm use 22 \ + && nvm alias default 22 + ENV PATH="$NVM_DIR/versions/node/v22.12.0/bin:$PATH" - ```bash - ntt init Testnet - ``` + # Install Bun + RUN curl -fsSL https://bun.sh/install | bash + ENV PATH="/root/.bun/bin:$PATH" -=== "Mainnet" + # Install Foundry + RUN curl -L https://foundry.paradigm.xyz | bash + ENV PATH="/root/.foundry/bin:${PATH}" + RUN /bin/bash -c "source /root/.bashrc && foundryup" - ```bash - ntt init Mainnet - ``` + # Install Wormhole NTT CLI + RUN curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash -Ensure you have set up your environment correctly: + # Add a default working directory + WORKDIR /app -```bash -export ETH_PRIVATE_KEY=INSERT_PRIVATE_KEY -``` + # Expose port for development if needed + EXPOSE 8899 -Add each chain you'll be deploying to. The following example demonstrates configuring NTT in burn-and-mint mode on Ethereum Sepolia and Arbitrum Sepolia: + # Entry point for the container + CMD ["bash"] + ``` -```bash -# Set scanner API Keys as environment variables -export SEPOLIA_SCAN_API_KEY=INSERT_ETHERSCAN_SEPOLIA_API_KEY -export ARBITRUMSEPOLIA_SCAN_API_KEY=INSERT_ARBISCAN_SEPOLIA_API_KEY + ???- interface "docker-compose.yml" + ```yml + services: + portal-ntt: + build: + context: . + dockerfile: Dockerfile + platform: linux/amd64 + volumes: + - ./src:/app + working_dir: /app + tty: true + ``` +--- END CONTENT --- -# Add each chain -# The contracts will be automatically verified using the scanner API keys above -ntt add-chain Sepolia --latest --mode burning --token INSERT_YOUR_TOKEN_ADDRESS -ntt add-chain ArbitrumSepolia --latest --mode burning --token INSERT_YOUR_TOKEN_ADDRESS -``` +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/overview/ +--- BEGIN CONTENT --- +--- +title: Native Token Transfers Overview +description: With Native Token Transfers, you can directly transfer a blockchain's native assets across various connected networks. +categories: NTT, Transfer +--- -While not recommended, you can pass the `-skip-verify` flag to the `ntt add-chain` command if you want to skip contract verification. +## Native Token Transfers Overview -The `ntt add-chain` command takes the following parameters: +Native Token Transfers (NTT) provides an adaptable framework for transferring your native tokens across different blockchains. Unlike traditional wrapped assets, NTT maintains your token's native properties on every chain. This ensures that you retain complete control over crucial aspects, such as metadata, ownership, upgradeability, and custom features. -- Name of each chain -- Version of NTT to deploy (use `--latest` for the latest contract versions) -- Mode (either `burning` or `locking`) -- Your token contract address +## Key Features -The NTT CLI prints detailed logs and transaction hashes, so you can see exactly what's happening under the hood. +- **Control and customization**: Ensure ownership and configurable access controls, permissions, and thresholds, preventing unauthorized calls. +- **Advanced rate limiting**: Set rate limits per chain and period to prevent abuse, manage network congestion, and control deployments. +- **Global accountant**: Ensures the amount burned and transferred on chains never exceeds the amount of tokens minted. +- **No wrapped tokens**: Tokens are used directly within their native ecosystem, eliminating intermediary transfer steps. -## Configure NTT -The NTT CLI takes inspiration from [git](https://git-scm.com/){target=\_blank}. You can run: +## Deployment Models -- `ntt status` - checks whether your `deployment.json` file is consistent with what is on-chain -- `ntt pull` - syncs your `deployment.json` file with the on-chain configuration and set up rate limits with the appropriate number of decimals, depending on the specific chain. For example: +NTT offers two operational modes for your existing tokens: - For Solana, the limits are set with 9 decimal places: - ```json - "inbound": { - "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana - } - ``` +- **Hub-and-spoke**: Locks tokens on a central "hub" chain and mints equivalents on "spoke" chains, maintaining the total supply on the hub. It's ideal for integrating existing tokens onto new blockchains without altering their original contracts. +- **Burn-and-mint**: Burns tokens on the source chain and mints new ones on the destination, distributing the total supply across multiple chains. It's best suited for new token deployments or projects willing to upgrade existing contracts for a truly native multichain token. - For Sepolia (Ethereum Testnet), the limits are set with 18 decimal places: - ```json - "inbound": { - "Solana": "1000.000000000000000000" // inbound limit from Solana to Sepolia - } - ``` +## Supported Token Standards - This initial configuration ensures that the rate limits are correctly represented for each chain's token precision - -- `ntt push` - syncs the on-chain configuration with local changes made to your `deployment.json` file +Native Token Transfers (NTT) primarily support ERC-20 tokens, the most widely used standard for fungible assets on Ethereum and other EVM-compatible chains, including ERC-20 Burnable tokens, which can be burned on the source chain during cross-chain transfers when required. It also supports fungible SPL tokens on Solana for secure cross-chain transfers. -After you deploy the NTT contracts, ensure that the deployment is properly configured and your local representation is consistent with the actual on-chain state by running `ntt status` and following the instructions shown on the screen. +The NttManager is a contract that oversees the secure and reliable transfer of native tokens across supported blockchains. It leverages the standard IERC20 interface and OpenZeppelin’s SafeERC20 library to interact with these tokens securely across chains. -## Set Token Minter to NTT Manager +NTT does not currently support token standards like ERC-721 (non-fungible tokens), ERC-1155 (a multi-token standard), or SPL-based tokens, such as Metaplex NFTs. Support is currently limited to ERC-20 tokens. -The final step in the deployment process is to set the NTT Manager as a minter of your token on all chains you have deployed to in `burning` mode. When performing a hub-and-spoke deployment, it is only necessary to set the NTT Manager as a minter of the token on each spoke chain. +## Deployment Process -!!! note - The required NTT Manager address can be found in the `deployment.json` file. +Here's a breakdown of the key steps involved when deploying NTT: -- If you followed the [`INttToken`](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} interface, you can execute the `setMinter(address newMinter)` function - ```json - cast send $TOKEN_ADDRESS "setMinter(address)" $NTT_MANAGER_ADDRESS --private-key $ETH_PRIVATE_KEY --rpc-url $YOUR_RPC_URL - ``` +- **Prepare tokens**: Ensure your ERC-20 or SPL tokens are ready. +- **Choose deployment model**: Choose your cross-chain token model: either burn-and-mint or hub-and-spoke. +- **Choose deployment tool**: Use the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for EVM chains only) or the [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank}. +- **Initialization**: Specify target chains and token details, and set up your CLI environment if using it. +- **Deploy contracts**: Deploy NTT Manager contracts to all selected chains, confirming transactions and covering gas fees. +- **Finalize configurations**: Grant minting authority, configure rate limits, establish peer manager connections, and assign administrative roles. +- **Monitor and maintain**: Verify deployment, monitor total supply with the [Global Accountant](/docs/products/native-token-transfers/concepts/security/#global-accountant){target=\_blank}, and adjust configurations as needed. -- If you have a custom process to manage token minters, you should now follow that process to add the corresponding NTT Manager as a minter +## Use Cases -By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. +- **Cross-Chain Swaps and Liquidity Aggregation** -!!!important - To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} page. ---- END CONTENT --- + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transmits native assets across chains. + - [**Connect**](/docs/products/connect/overview/): Manages user-friendly asset transfers. + - [**Queries**](/docs/products/queries/overview/): Acquires real-time prices for optimal trade execution. -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Solana Deployment -description: Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. -categories: NTT, Transfer ---- +- **Borrowing and Lending Across Chains** -# Deploy Native Token Transfers on Solana + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Moves collateral as native assets. + - [**Messaging**](/docs/products/messaging/overview/): Propagates loan requests and liquidations across chains. + - [**Queries**](/docs/products/queries/overview/): Retrieves interest rates and asset prices in real-time. -[Native Token Transfers (NTT)](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. +- **Gas Abstraction** -This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Facilitates native token conversion for gas payments. + - [**Messaging**](/docs/products/messaging/overview/): Sends gas fee payments across chains. -By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. +- **Cross-Chain Payment Widgets** -## Prerequisites + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Ensures direct, native asset transfers. + - [**Connect**](/docs/products/connect/overview/): Facilitates seamless payments in various tokens. -Before deploying NTT on Solana, ensure you have the following: +- **Cross-Chain Staking** -- [Rust](https://www.rust-lang.org/tools/install){target=\_blank} -- [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** -- [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transfers staked assets natively between networks. + - [**Messaging**](/docs/products/messaging/overview/): Moves staking rewards and governance signals across chains. -Use the Solana and Anchor versions listed above to avoid compatibility issues while following this guide. +## Next Steps -## Overview of the Deployment Process +Follow these steps to get started with NTT: -Deploying NTT with the CLI on Solana follows a structured process: +[timeline(wormhole-docs/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json)] +--- END CONTENT --- -1. **Choose your token setup**: +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/cli-commands/ +--- BEGIN CONTENT --- +--- +title: NTT CLI Commands +description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +categories: NTT, Transfer +--- - - **Use an existing SPL token** - if your token is already deployed on Solana, you can skip token creation and move directly to the [Set Up NTT](#set-up-ntt) section - - **Create a new SPL token** - if you don't already have an SPL token deployed, you'll need to deploy and configure it on Solana before integrating with Wormhole's NTT +# NTT CLI Commands - ???- interface "Create and Mint SPL Tokens" - This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. +## Introduction - 1. **Generate a Solana key pair** - run the following command to create a new wallet: +The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. - ```bash - solana-keygen grind --starts-with w:1 --ignore-case - ``` +If you haven't installed the NTT CLI yet, follow the [NTT Installation](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank} instructions to set it up before proceeding. - 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: +## Table of Commands - ```bash - solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON - ``` +The following table lists the available NTT CLI commands, descriptions, and examples. - 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: +To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. - === "Mainnet" - ```bash - solana config set -um - ``` +### General Commands - === "Testnet" - ```bash - solana config set -ut - ``` +| Command | Description | Example | +|-----------------------------------------|--------------------------------------------------------|--------------------------------------------------------------------| +| `ntt update` | update the NTT CLI | `ntt update` | +| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | +| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest` | +| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0` | +| `ntt clone
` | initialize a deployment file from an existing contract | `ntt clone Mainnet Solana Sol5678...` | +| `ntt init ` | initialize a deployment file | `ntt init devnet` | +| `ntt pull` | pull the remote configuration | `ntt pull` | +| `ntt push` | push the local configuration | `ntt push` | +| `ntt status` | check the status of the deployment | `ntt status` | - === "Devnet" - ```bash - solana config set -ud - ``` +### Configuration Commands - 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: +| Command | Description | Example | +|----------------------------------------------|-----------------------------------------|------------------------------------------------| +| `ntt config set-chain ` | set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key` | +| `ntt config unset-chain ` | unset a configuration value for a chain | `ntt config unset-chain Ethereum scan_api_key` | +| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key` | - ```bash - solana airdrop 2 - solana balance - ``` +### Solana Commands - 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} +| Command | Description | Example | +|------------------------------------------------|----------------------------------------------------------|-------------------------------------------------| +| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json` | +| `ntt solana token-authority ` | print the token authority address for a given program ID | `ntt solana token-authority Sol1234...` | +| `ntt solana ata ` | print the token authority address for a given program ID | `ntt solana ata Mint123... Owner123... token22` | - ```bash - cargo install spl-token-cli - ``` +## Where to Go Next - 6. **Create a new SPL token** - initialize the token on Solana +
- ```bash - spl-token create-token - ``` - 7. **Create a token account** - generate an account to hold the token +- :octicons-gear-16:{ .lg .middle } **Configure NTT** - ```bash - spl-token create-account INSERT_TOKEN_ADDRESS - ``` + --- - 8. **Mint tokens** - send 1000 tokens to the created account + Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. - ```bash - spl-token mint INSERT_TOKEN_ADDRESS 1000 - ``` + [:custom-arrow: Configure your NTT deployment](/docs/products/native-token-transfers/configuration/access-control/) - !!! note - NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. +- :octicons-question-16:{ .lg .middle } **NTT FAQs** -2. **Choose your [deployment model](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank}**: + --- - - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required - - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program + Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. -3. **Deploy and configure NTT** - use the NTT CLI to initialize and deploy the NTT program, specifying your SPL token and deployment mode + [:custom-arrow: Check out the FAQs](/docs/products/native-token-transfers/faqs/) -Following this process, your token will fully integrate with NTT, enabling seamless transfers between Solana and other chains. +
+--- END CONTENT --- -By default, NTT transfers to Solana require manual [relaying](/docs/learn/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. +Doc-Content: https://wormhole.com/docs/products/native-token-transfers/reference/managers-transceivers/ +--- BEGIN CONTENT --- +--- +title: Managers and Transceivers +description: Explore the roles of Managers and Transceivers in NTT cross-chain token transfers, including key functions, lifecycle events, and rate-limiting mechanisms. +categories: NTT, Transfer +--- -## Set Up NTT +# Managers and Transceivers -To integrate your token with NTT on Solana, you must initialize the deployment and configure its parameters. This process sets up the required contracts and may generate key pairs if they don't exist. These key pairs are used to sign transactions and authorize actions within the NTT deployment. +## Managers -The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: +_Managers_ oversee the token transfer process and handle rate-limiting and message attestation. They manage interactions with multiple transceivers and ensure that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. Each NTT manager corresponds to a single token but can control multiple transceivers. Key functions include: -1. **Create a new NTT project** - set up a deployment workspace +- **`transfer`** - initiate the transfer process where tokens on the source chain are locked or burned. This process ensures that an equivalent amount of tokens can be minted or unlocked on the destination chain - ```bash - ntt new INSERT_PROJECT_NAME - cd INSERT_PROJECT_NAME + ```solidity + function transfer( + uint256 amount, // amount (in atomic units) + uint16 recipientChain, // chain ID (Wormhole formatted) + bytes32 recipient // recipient address (Wormhole formatted) + ) external payable nonReentrant whenNotPaused returns (uint64) ``` -2. **Initialize the deployment** - generate a `deployment.json` file with your deployment settings +- **`quoteDeliveryPrice`** - calculate the cost of sending messages across chains by querying the transceivers for estimates on message delivery fees, allowing users to know the price before initiating a transfer - === "Mainnet" + ```solidity + function quoteDeliveryPrice( + uint16 recipientChain, // chain ID (Wormhole formatted) + bytes memory transceiverInstructions // extra instructions for transceivers (Transceiver-dependent on whether extra instructions are used/accepted) + ) public view returns (uint256[] memory, uint256) + ``` - ```bash - ntt init Mainnet - ``` +- **`setPeer`** - to maintain secure cross-chain communication, managers establish trust relationships between different instances of NTT manager contracts across chains. By recognizing each other as peers, they ensure that the token transfers happen securely and that rate limits on inbound transactions are respected - === "Testnet" + ```solidity + function setPeer( + uint16 peerChainId, // chain ID (Wormhole formatted) + bytes32 peerContract, // peer NTT Manager address (Wormhole formatted) + uint8 decimals, // token decimals on the peer chain + uint256 inboundLimit // inbound rate limit (in atomic units) + ) public onlyOwner + ``` - ```bash - ntt init Testnet - ``` -!!! note - Testnet deployment settings work for both Solana Testnet and Devnet networks. +## Transceivers +_Transceivers_ are responsible for routing NTT transfers through the manager on the source chain and ensuring they are delivered to the corresponding manager on the recipient chain. They work with managers to ensure that messages are accurately processed and tokens are correctly transferred, providing a reliable system for cross-chain token transfers. Transceivers can be defined independently of the Wormhole core and modified to support any verification backend. Key functions: -### Generate an NTT Program Key Pair +- **`sendMessage`** - this external function sends token transfer messages to a specified recipient chain. It encodes the token transfer details into a message format recognized by the system -Create a unique key pair for the NTT program: - - ```bash - solana-keygen grind --starts-with ntt:1 --ignore-case + ```solidity + function sendMessage( + uint16 recipientChain, // chain ID (Wormhole formatted) + TransceiverStructs.TransceiverInstruction memory instruction, // extra instruction for the Transceiver (optional, dependent on whether extra instructions are used/accepted for this Transceiver) + bytes memory nttManagerMessage, // serialized NTT Manager message, provided by the NTT Manager + bytes32 recipientNttManagerAddress, // NTT Manager address on the recipient chain (Wormhole formatted) + bytes32 refundAddress // address to receive refunds on the destination chain in case of excess quotes (Wormhole formatted) + ) external payable nonReentrant onlyNttManager ``` -### Set Mint Authority +- **`quoteDeliveryPrice`** - provides an estimation of the cost associated with delivering a message to a target chain and gauges transaction fees -If you use burn-and-mint mode, follow these steps to enable the NTT program to mint tokens on Solana. This involves deriving the PDA as the token authority and updating the SPL token's minting permissions. + ```solidity + function quoteDeliveryPrice( + uint16 targetChain, // chain ID (Wormhole formatted) + TransceiverStructs.TransceiverInstruction memory instruction // extra instruction for the Transceiver (optional, dependent on whether extra instructions are used/accepted for this Transceiver) + ) external view returns (uint256) + ``` -If you want to use hub-and-spoke, skip this section and proceed to [Deploy and Configure NTT](#deploy-and-configure-ntt). +## Lifecycle of a Message -Before updating the mint authority, you must create metadata for your SPL token. You can visit this repository to see an example of [how to create metadata for your SPL token](https://github.com/wormhole-foundation/demo-metaplex-metadata/blob/main/src/token-metadata.ts){target=\_blank}. +### EVM -Follow these steps to set the mint authority using the NTT CLI: +#### Transfer -1. **Derive the token authority** - generate the PDA, which will manage token minting +A client calls on `transfer` to initiate an NTT transfer. The client must specify, at minimum, the transfer amount, the recipient chain, and the recipient address on the recipient chain. `transfer` also supports a flag to specify whether the `NttManager` should queue rate-limited transfers or revert. Clients can also include additional instructions to forward along to the transceiver on the source chain. Depending on the mode set in the initial configuration of the `NttManager` contract, transfers are either "locked" or "burned." Once the transfer has been forwarded to the transceiver, the `NttManager` emits the `TransferSent` event. - ```bash - ntt solana token-authority INSERT_YOUR_NTT_PROGRAM_KEY_PAIR - ``` +**Events** -2. **Set SPL token mint authority** - delegate minting control to the derived PDA +```ts +/// @notice Emitted when a message is sent from the nttManager. +/// @dev Topic0 +/// 0x9716fe52fe4e02cf924ae28f19f5748ef59877c6496041b986fbad3dae6a8ecf +/// @param recipient The recipient of the message. +/// @param amount The amount transferred. +/// @param fee The amount of ether sent along with the tx to cover the delivery fee. +/// @param recipientChain The chain ID of the recipient. +/// @param msgSequence The unique sequence ID of the message. +event TransferSent( + bytes32 recipient, uint256 amount, uint256 fee, uint16 recipientChain, uint64 msgSequence +); +``` - ```bash - spl-token authorize INSERT_TOKEN_ADDRESS mint INSERT_DERIVED_PDA - ``` +#### Rate Limit -## Deploy and Configure NTT +A transfer can be rate-limited on both the source and destination chains. If a transfer is rate-limited on the source chain and the `shouldQueue` flag is enabled, it is added to an outbound queue. The transfer can be released after the configured `_rateLimitDuration` has expired via the `completeOutboundQueuedTransfer` method. The `OutboundTransferQueued` and `OutboundTransferRateLimited` events are emitted. -!!! warning - If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/build/transfers/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. +If the client attempts to release the transfer from the queue before the expiry of the `rateLimitDuration`, the contract reverts with an `OutboundQueuedTransferStillQueued` error. +Similarly, rate-limited transfers on the destination chain are added to an inbound queue. These transfers can be released from the queue via the `completeInboundQueuedTransfer` method, and the `InboundTransferQueued` event is emitted. -After setting up your deployment, finalize the configuration and deploy the NTT program on Solana by following these steps: +If the client attempts to release the transfer from the queue before the `rateLimitDuration` expires, the contract reverts with an `InboundQueuedTransferStillQueued` error. -1. **Deploy NTT to Solana** - run the appropriate command based on your deployment mode: +To deactivate the rate limiter, set `_rateLimitDuration` to 0 and enable the `_skipRateLimiting` field in the `NttManager` constructor. Configuring this incorrectly will throw an error. If the rate limiter is deactivated, the inbound and outbound rate limits can be set to 0. - === "Burn-and-Mint" +**Events** - ```bash - ntt add-chain Solana --latest --mode burning --token INSERT_TOKEN_ADDRESS --payer INSERT_YOUR_KEYPAIR_JSON --program-key INSERT_YOUR_NTT_PROGRAM_KEYPAIR_JSON - ``` +```ts +/// @notice Emitted whenn an outbound transfer is queued. +/// @dev Topic0 +/// 0x69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f. +/// @param queueSequence The location of the transfer in the queue. +event OutboundTransferQueued(uint64 queueSequence); +``` - === "Hub-and-Spoke" +```ts +/// @notice Emitted when an outbound transfer is rate limited. +/// @dev Topic0 +/// 0x754d657d1363ee47d967b415652b739bfe96d5729ccf2f26625dcdbc147db68b. +/// @param sender The initial sender of the transfer. +/// @param amount The amount to be transferred. +/// @param currentCapacity The capacity left for transfers within the 24-hour window. +event OutboundTransferRateLimited( + address indexed sender, uint64 sequence, uint256 amount, uint256 currentCapacity +); +``` - ```bash - ntt add-chain Solana --latest --mode locking --token INSERT_TOKEN_ADDRESS --payer INSERT_YOUR_KEYPAIR_JSON --program-key INSERT_YOUR_NTT_PROGRAM_KEYPAIR_JSON - ``` +```ts +/// @notice Emitted when an inbound transfer is queued +/// @dev Topic0 +/// 0x7f63c9251d82a933210c2b6d0b0f116252c3c116788120e64e8e8215df6f3162. +/// @param digest The digest of the message. +event InboundTransferQueued(bytes32 digest); +``` - You can optionally add `--solana-priority-fee` to the script to increase the priority fee in microlamports. The default is `50000`. +#### Send -2. **Verify deployment status** - after deployment, check if your `deployment.json` file matches the on-chain configuration using the following command: +Once the `NttManager` forwards the message to the transceiver, the message is transmitted via the `sendMessage method`. The method signature is enforced by the transceiver but transceivers are free to determine their own implementation for transmitting messages. (e.g. a message routed through the Wormhole transceiver can be sent via Wormhole relaying, a custom relayer, or manually published via the core bridge). - ```bash - ntt status - ``` - - If needed, sync your local configuration with the on-chain state: - - ```bash - ntt pull - ``` - -3. **Configure inbound and outbound rate limits** - by default, the inbound and outbound limits are set to `0` and must be updated before deployment. For EVM chains, values must be set using 18 decimals, while Solana uses nine decimals. +Once the message has been transmitted, the contract emits the `SendTransceiverMessage` event. - Open your `deployment.json` file and adjust the values based on your use case: +**Events** - ```json - "inbound": { - "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana - }, - "outbound": { - "Sepolia": "1000.000000000" // outbound limit from Solana to Sepolia - } - ``` +```ts +/// @notice Emitted when a message is sent from the transceiver. +/// @dev Topic0 +/// 0x53b3e029c5ead7bffc739118953883859d30b1aaa086e0dca4d0a1c99cd9c3f5. +/// @param recipientChain The chain ID of the recipient. +/// @param message The message. +event SendTransceiverMessage( + uint16 recipientChain, TransceiverStructs.TransceiverMessage message +); +``` -4. **Push the final deployment** - once rate limits are set, push the deployment to Solana using the specified key pair to cover gas fees +#### Receive - ```bash - ntt push --payer INSERT_YOUR_KEYPAIR_JSON - ``` +Once a message has been emitted by a transceiver on the source chain, an off-chain process (for example, a relayer) will forward the message to the corresponding transceiver on the recipient chain. The relayer interacts with the transceiver via an entry point to receive messages. For example, the relayer will call the `receiveWormholeMessage` method on the `WormholeTransceiver` contract to execute the message. The `ReceiveRelayedMessage` event is emitted during this process. -### Recovering Rent for Failed Solana Deployments +This method should also forward the message to the `NttManager` on the destination chain. Note that the transceiver interface doesn't declare a signature for this method because receiving messages is specific to each transceiver, and a one-size-fits-all solution would be overly restrictive. -Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked in deployment buffer accounts that persist after interruptions. To recover these funds, refer to the [Solana program deployment guide](https://solana.com/docs/programs/deploying#program-buffer-accounts){target=\_blank} for instructions on identifying and closing these buffer accounts. +The `NttManager` contract allows an M of N threshold for transceiver attestations to determine whether a message can be safely executed. For example, if the threshold requirement is 1, the message will be executed after a single transceiver delivers a valid attestation. If the threshold requirement is 2, the message will only be executed after two transceivers deliver valid attestations. When a transceiver attests to a message, the contract emits the `MessageAttestedTo` event. -## Where to Go Next +NTT implements replay protection, so if a given transceiver attempts to deliver a message attestation twice, the contract reverts with `TransceiverAlreadyAttestedToMessage` error. NTT also implements replay protection against re-executing messages. This check also acts as reentrancy protection as well. -
+If a message has already been executed, the contract ends execution early and emits the `MessageAlreadyExecuted` event instead of reverting via an error. This mitigates the possibility of race conditions from transceivers attempting to deliver the same message when the threshold is less than the total number of available of transceivers (i.e. threshold < totalTransceivers) and notifies the client (off-chain process) so they don't attempt redundant message delivery. -- :octicons-globe-16:{ .lg .middle } **Deploy NTT on EVM Chains** +**Events** - --- +```ts +/// @notice Emitted when a relayed message is received. +/// @dev Topic0 +/// 0xf557dbbb087662f52c815f6c7ee350628a37a51eae9608ff840d996b65f87475 +/// @param digest The digest of the message. +/// @param emitterChainId The chain ID of the emitter. +/// @param emitterAddress The address of the emitter. +event ReceivedRelayedMessage(bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress); +``` - After deploying NTT on Solana, deploy and integrate it on EVM chains to enable seamless multichain transfers. +```ts +/// @notice Emitted when a message is received. +/// @dev Topic0 +/// 0xf6fc529540981400dc64edf649eb5e2e0eb5812a27f8c81bac2c1d317e71a5f0. +/// @param digest The digest of the message. +/// @param emitterChainId The chain ID of the emitter. +/// @param emitterAddress The address of the emitter. +/// @param sequence The sequence of the message. +event ReceivedMessage( + bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence +); +``` - [:custom-arrow: Deploy NTT on EVM](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} +```ts +/// @notice Emitted when a message has already been executed to notify client of against retries. +/// @dev Topic0 +/// 0x4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef2. +/// @param sourceNttManager The address of the source nttManager. +/// @param msgHash The keccak-256 hash of the message. +event MessageAlreadyExecuted(bytes32 indexed sourceNttManager, bytes32 indexed msgHash); +``` -- :octicons-tools-16:{ .lg .middle } **Test Your Deployment** +#### Mint or Unlock - --- +Once a transfer has been successfully verified, the tokens can be minted (if the mode is "burning") or unlocked (if the mode is "locking") to the recipient on the destination chain. Note that the source token decimals are bounded between `0` and `TRIMMED_DECIMALS` as enforced in the wire format. The transfer amount is untrimmed (scaled-up) if the destination chain token decimals exceed `TRIMMED_DECIMALS`. Once the appropriate number of tokens have been minted or unlocked to the recipient, the `TransferRedeemed` event is emitted. - Follow the NTT Post Deployment Guide for integration examples and testing instructions. +**Events** - [:custom-arrow: Test Your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} +```ts +/// @notice Emitted when a transfer has been redeemed +/// (either minted or unlocked on the recipient chain). +/// @dev Topic0 +/// 0x504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a91. +/// @param digest The digest of the message. +event TransferRedeemed(bytes32 indexed digest); +``` -- :octicons-tools-16:{ .lg .middle } **Add NTT to Your dApp** +### Solana - --- +#### Transfer - Configure Wormhole Connect, a plug-and-play bridging UI, to enable multichain transfers for your token. +A client calls the `transfer_lock` or `transfer_burn` instruction based on whether the program is in `LOCKING` or `BURNING` mode. The program mode is set during initialization. When transferring, the client must specify the amount of the transfer, the recipient chain, the recipient address on the recipient chain, and the boolean flag `should_queue` to specify whether the transfer should be queued if it hits the outbound rate limit. If `should_queue` is set to false, the transfer reverts instead of queuing if the rate limit were to be hit. - [:custom-arrow: Use Connect to Integrate NTT](/docs/build/transfers/connect/){target=\_blank} +!!! note + Using the wrong transfer instruction, i.e. `transfer_lock` for a program that is in `BURNING` mode, will result in an `InvalidMode` error. -- :octicons-question-16:{ .lg .middle } **View FAQs** +Depending on the mode and instruction, the following will be produced in the program logs: - --- +```ts +Program log: Instruction: TransferLock +Program log: Instruction: TransferBurn +``` - Find answers to common questions about NTT. +Outbound transfers are always added to an Outbox via the `insert_into_outbox` method. This method checks the transfer against the configured outbound rate limit amount to determine whether the transfer should be rate-limited. An `OutboxItem` is a Solana Account that holds details of the outbound transfer. The transfer can be released from the Outbox immediately if no rate limit is hit. The transfer can be released from the Outbox immediately unless a rate limit is hit, in which case it will only be released after the delay duration associated with the rate limit has expired. - [:custom-arrow: View FAQs](/docs/build/transfers/native-token-transfers/faqs){target=\_blank} +#### Rate Limit -
---- END CONTENT --- +During the transfer process, the program checks rate limits via the `consume_or_delay` function. The Solana rate-limiting logic is equivalent to the EVM rate-limiting logic. -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ ---- BEGIN CONTENT --- ---- -title: Deploy Native Token Transfers with Launchpad -description: Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. -categories: NTT, Transfer ---- +If the transfer amount fits within the current capacity: -# Deploy Native Token Transfers with Launchpad +- Reduce the current capacity +- Refill the inbound capacity for the destination chain +- Add the transfer to the Outbox with `release_timestamp` set to the current timestamp, so it can be released immediately. -## Introduction +If the transfer amount doesn't fit within the current capacity: -The [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT across multiple blockchains. +- If `shouldQueue = true`, add the transfer to the Outbox with `release_timestamp` set to the current timestamp plus the configured `RATE_LIMIT_DURATION`. +- If `shouldQueue = false`, revert with a `TransferExceedsRateLimit` error -Instead of manually deploying contracts on each chain, configuring relayers, and managing cross-chain communication, you can quickly launch or expand tokens with just a few clicks. +#### Send -The Launchpad automates deployment, reducing complexity and saving time. +The caller then needs to request each transceiver to send messages via the `release_outbound` instruction. To execute this instruction, the caller needs to pass the account of the Outbox item to be released. The instruction will then verify that the transceiver is one of the specified senders for the message. Transceivers then send the messages based on the verification backend they are using. -This guide covers: +For example, the Wormhole transceiver will send by calling `post_message` on the Wormhole program, so that the Wormhole Guardians can observe and verify the message. - - Launching a new cross-chain token - - Expanding an existing token for NTT - - Managing tokens via the dashboard and settings +!!! note + When `revert_on_delay` is true, the transaction will revert if the release timestamp hasn't been reached. When `revert_on_delay` is false, the transaction succeeds, but the outbound release isn't performed. -## Prerequisites +The following will be produced in the program logs: - - An EVM-compatible wallet (e.g., [MetaMask](https://metamask.io/){target=\_blank}, [Phantom](https://phantom.com/){target=\_blank}, etc.) - - Minimum ETH (or equivalent) for gas fees per deployment +```ts +Program log: Instruction: ReleaseOutbound +``` -## Supported Blockchains +#### Receive -The NTT Launchpad currently supports deployments on the following mainnet chains: +Similar to EVM, transceivers vary in how they receive messages since message relaying and verification methods may differ between implementations. - - Ethereum - - Arbitrum One - - Base - - Berachain - - Blast - - BNB Smart Chain - - Ink - - Optimism Mainnet - - Polygon +The Wormhole transceiver receives a verified Wormhole message on Solana via the `receive_message` entrypoint instruction. Callers can use the `receive_wormhole_message` Anchor library function to execute this instruction. The instruction verifies the Wormhole Verified Action Approvals (VAAs) and stores it in a `VerifiedTransceiverMessage` account. -## Choose Your Path +The following will be produced in the program logs: -Once ready, choose an option to proceed: +```ts +Program log: Instruction: ReceiveMessage +``` - - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token) - deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains - - [**Expand Your Existing Token**](#expand-your-existing-token) - if you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract +`redeem` checks the inbound rate limit and places the message in an Inbox. Logic works the same as the outbound rate limit mentioned previously. -## Launch a Cross-Chain Token +The following will be produced in the program logs: -Deploy a new NTT-compatible token that can be transferred across multiple chains. This process sets up your token on a home network and deploys it to additional blockchains. Follow the below steps to get started: +```ts +Program log: Instruction: Redeem +``` -1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** +#### Mint or Unlock - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) - -2. Select **Launch a Cross-Chain Token** +The inbound transfer is released and the tokens are unlocked or minted to the recipient through either `release_inbound_mint` if the mode is `BURNING`, or `release_inbound_unlock` if the mode is `LOCKING`. Similar to transfer, using the wrong transfer instruction (such as `release_inbound_mint` for a program that is in locking mode) will result in `InvalidMode` error. - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp) +!!! note + When `revert_on_delay` is true, the transaction will revert if the release timestamp hasn't been reached. When `revert_on_delay` is false, the transaction succeeds, but the minting/unlocking isn't performed. -3. Set the token details: - 1. Select the **home network** from the dropdown menu - 2. Enter the **name** for the token - 3. Enter the **symbol** of the token - 4. Provide the **initial supply** - 5. To the token details, click **Next** +Depending on the mode and instruction, the following will be produced in the program logs: - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp) +```ts +Program log: Instruction: ReleaseInboundMint +Program log: Instruction: ReleaseInboundUnlock +``` +--- END CONTENT --- -4. Select the deployment chains: - 1. The home network where your token will be deployed will be populated (e.g., Optimism) - 2. Choose any additional chains to deploy your token to (e.g., Base) - 3. To continue, click **Next** +Doc-Content: https://wormhole.com/docs/products/products/ +--- BEGIN CONTENT --- +--- +title: Compare Wormhole's Cross-Chain Solutions +description: Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +categories: Transfer, Basics +--- - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp) +# Products -5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction +Wormhole provides a comprehensive suite of cross-chain solutions, enabling seamless asset transfers, data retrieval, and governance across blockchain ecosystems. - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) +Wormhole provides multiple options for asset transfers: Connect for a plug-and-play bridging UI, Native Token Transfers (NTT) for moving native assets without wrapped representations, and Token Bridge for a secure lock-and-mint mechanism. -6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet +Beyond transfers, Wormhole extends interoperability with tools for cross-chain data access, decentralized governance, and an intent-based protocol through Wormhole Settlement. - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) +## Transfer Products -7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step +Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -8. Once both deployments are completed, proceed to the [**Dashboard**](#explore-the-launchpad-dashboard) to manage your token. +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -## Expand Your Existing Token +
-Expand an existing token to support NTT across multiple chains. This process integrates your deployed token with NTT without modifying its original contract. Follow the steps below to get started: +::spantable:: -1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** +| | Criteria | NTT | Token Bridge | Settlement | +|--------------------------------|---------------------------------------|--------------------|--------------------|--------------------| +| Supported Transfer Types @span | Token Transfers | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| | Token Transfers with Payloads | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Supported Assets @span | Wrapped Assets | :x: | :white_check_mark: | :white_check_mark: | +| | Native Assets | :white_check_mark: | :x: | :white_check_mark: | +| | ERC-721s (NFTs) | :x: | :white_check_mark: | :white_check_mark: | +| Features @span | Out-of-the-Box UI | :x: | :x: | :white_check_mark: | +| | Event-Based Actions | :white_check_mark: | :white_check_mark: | :x: | +| | Intent-Based Execution | :x: | :x: | :white_check_mark: | +| | Fast Settlement | :x: | :x: | :white_check_mark: | +| | Liquidity Optimization | :x: | :x: | :white_check_mark: | +| Integration Details @span | | | | | +| Requirements @span | Contract Deployment | :white_check_mark: | :x: |:x: | +| Ease of Integration | Implementation Complexity | :green_circle: :green_circle: :white_circle:
Moderate | :green_circle: :green_circle: :white_circle:
Moderate |:green_circle: :white_circle: :white_circle:
Low | +| Technology @span | Supported Languages | Solidity, Rust | Solidity, Rust, TypeScript | TypeScript | - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) +::end-spantable:: -2. Select **Expand Your Existing Token** +
- ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp) +In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: -3. Enter the token details: - 1. Choose the home network where your token is already deployed (e.g., Optimism) - 2. Choose any additional chains to deploy your token to (e.g., Base) - 3. To continue, click **Next** +
- ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp) +Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. -4. Select the chains to deploy your token to: - 1. The home network where your token is already deployed will be populated (e.g., Optimism) - 2. Choose any additional chains to deploy your token to (e.g., Base) - 1. Click **Next** +## Bridging UI - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp) +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. -5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction +## Real-time Data - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. -6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet +## Multichain Governance - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. +--- END CONTENT --- -7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step - -8. Now that your token has been deployed on multiple chains click [**Dashboard**](#explore-the-launchpad-dashboard) to review its details - -## Explore the Launchpad Dashboard - -To access the **Dashboard** from the [Launchpad home page](https://ntt.wormhole.com/){target=\_blank}, click on **Manage Deployment**. Here, you can view deployment status, monitor supply across chains, and configure transfer settings. - -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp) - -The dashboard provides a high-level view of your token across all deployed chains, including: - - - Token addresses for each chain - - Supply distribution visualization - - List of deployed chains, including inbound and outbound transfer limits, which can be modified in [**Settings**](#settings) - -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp) - -## Settings +Doc-Content: https://wormhole.com/docs/products/queries/faqs/ +--- BEGIN CONTENT --- +--- +title: Queries FAQs +description: Wormhole Queries FAQ covering available libraries, query examples, response formats, and details about running query proxy servers. +categories: Queries +--- -The **Settings** page allows you to configure security parameters, role management, and transfer limits for your deployed token. You can switch between chains to manage these settings independently for each deployment. +# Wormhole Queries FAQs -### Chain Management +## What libraries are available to handle queries? -Use the drop-down menu at the top to select the chain you want to configure. The available options correspond to the chains where your token has already been deployed. Once selected, the page displays token details specific to that chain. + - The [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} can be used to create query requests, mock query responses for testing, and parse query responses. The SDK also includes utilities for posting query responses -From this section, you can also: +- The [Solidity `QueryResponseLib` library](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/QueryResponse.sol){target=\_blank} can be used to parse and verify query responses on EVM chains. See the [Solana Stake Pool](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} repository as an example use case - - **Pause the token** – temporarily turn off transfers on the selected chain - - **Deploy to a new chain** – expand your token by deploying it to an additional chain +- [`QueryRequestBuilder.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/testing/QueryRequestBuilder.sol){target=\_blank} can be used for mocking query requests and responses in Forge tests -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp) +- The [Go query package](https://github.com/wormhole-foundation/wormhole/tree/main/node/pkg/query){target=\_blank} can also be used to create query requests and parse query responses -### Role Management +!!! note + A Rust SDK for Solana is being actively investigated by the Wormhole contributors. See the [Solana Queries Verification](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} repository as a proof of concept. -This section displays key [roles](/docs/build/transfers/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. +## Are there any query examples? - - **Manager’s Owner** – the owner through the `NTTOwner` proxy - - **Pauser** – the address authorized to pause transfers +Certainly. You can find a complete guide on the [Use Queries page](/docs/products/queries/guides/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp) +- [Basic Example Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} +- [Solana Stake Pool Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} +- [Solana Program Derived Address (PDA) / Token Account Balance Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-pda){target=\_blank} +- [Solana Queries Verification Example](https://github.com/wormholelabs-xyz/example-queries-solana-verify){target=\_blank} -### Security Threshold +## What is the format of the response signature? -Determine and update how transceivers interact with the token. [Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. +The Guardian node calculates an ECDSA signature using [`Sign` function of the crypto package](https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.21/crypto#Sign){target=\_blank} where the digest hash is: -A higher transceiver threshold increases security by requiring more approvals before processing a transfer, but it may also slow down transactions. A lower threshold allows faster transfers but reduces redundancy in message verification. +```keccak256("query_response_0000000000000000000|"+keccak256(responseBytes))``` - - **Registered Transceivers** – displays the number of registered transceivers and their addresses - - **Transceivers Threshold** – a configurable value that must be less than or equal to the number of transceivers +See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_signer.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp) +!!! note + If you are used to `ecrecover` you will notice that the `v` byte is `0` or `1` as opposed to `27` or `28`. The `signaturesToEvmStruct` method in the [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} accounts for this as well as structuring the signatures into an `IWormhole.SignatureStruct[]`. -### Peer Chains Limits +## Can anyone run a query proxy server? -Define the transfer restrictions for each connected network. You can adjust: +Permissions for Query Proxy are managed by the Guardians. The Guardian nodes are configured to only listen to a set of allow-listed proxies. However, it is possible that this restriction may be lifted in the future and/or more proxies could be added. - - **Sending Limits** – the maximum amount of tokens that can be sent from the home chain - - **Receiving Limits** – the maximum amount of tokens that can be received for each of the supported peer chains +It is also important to note that the proxies don't impact the verifiability of the request or result, i.e., their role in the process is trustless. -Enter a new value to adjust limits and click **Update**. The changes will take effect immediately. +## What Does Queries Offer over an RPC Service -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp) +Wormhole Queries provides on-demand, attested, on-chain, verifiable RPC results. Each Guardian independently executes the specified query and returns the result and their signature. The proxy handles aggregating the results and signatures, giving you a single result (all within one REST call) with a quorum of signatures suitable for on-chain submission, parsing, and verification using one of our examples or SDKs. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/ +Doc-Content: https://wormhole.com/docs/products/queries/get-started/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) - Deployment -description: This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. -categories: NTT, Transfer +title: Get Started with Queries +description: Follow this guide to run your first multichain, verifiable query with the Wormhole Queries SDK and Proxy, using eth_call to fetch token metadata. +categories: Queries --- -# Deploy Native Token Transfers (NTT) - -## Get Started - -This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. - -
- -- :octicons-download-16:{ .lg .middle } **Installation** - - --- - - Prerequisites and commands for installing the NTT CLI and working with the NTT framework. - - [:custom-arrow: Install the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM** - - --- - - Find information on preparing for NTT deployment to EVM, including an example NTT token repository. - - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains via Launchpad** - - --- - - Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. - - [:custom-arrow: Deploy via Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/) - -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +# Get Started with Queries - --- - - Your guide to NTT deployment to Solana, including setup, token compatibility, mint/burn modes, and CLI usage. - - [:custom-arrow: Deploy token and NTT contracts](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) - -- :octicons-search-16:{ .lg .middle } **Post Deployment** - - --- - - Learn how to best monitor and maintain your NTT deployment to get the most out of your Wormhole integration while providing security for users. - - [:custom-arrow: Explore next steps](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) - -- :octicons-alert-16:{ .lg .middle } **Troubleshooting** - - --- - - Explore solutions and detailed guidance in our troubleshooting guide to resolve issues with NTT deployment. +## Introduction - [:custom-arrow: Get help](/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/) +[Queries](/docs/products/queries/overview) lets you fetch on-chain data from supported blockchains using `eth_call`-style requests without submitting transactions or paying gas. The Guardian network signs the result, making it verifiable and suitable for use on-chain. -
---- END CONTENT --- +This guide walks you through requesting an API key, constructing your first query using the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, and decoding the result. -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/installation/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Installation -description: Learn how to Install Wormhole’s Native Token Transfers (NTT) framework, a flexible and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- +## Prerequisites -# Install the Native Token Transfers CLI +Before you begin, make sure you have the following: -In this video, the Wormhole team walks you through installing the [Native Token Transfers (NTT) CLI](https://github.com/wormhole-foundation/native-token-transfers/tree/main/cli){target=\_blank}. You’ll see a practical demonstration of running commands, verifying your installation, and addressing common issues that might arise. If you prefer to follow written instructions or want a quick reference for each step, scroll down for the detailed installation guide. + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - A basic understanding of JavaScript or TypeScript + - An RPC endpoint for a supported chain (e.g., Ethereum Sepolia) + - A Wormhole Queries API key -To start using the NTT CLI, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. +## Request an API Key -
+Wormhole Queries is in closed beta, but you can start building today. -## Install NTT CLI +To interact with the system, you will use the Query Proxy. This hosted service receives your query, routes it to the appropriate chain, and returns a signed, verifiable response from the Guardian network. The Query Proxy allows you to fetch on-chain data without infrastructure overhead. -The fastest way to deploy Native Token Transfers (NTT) is using the NTT CLI. As prerequisites, ensure you have the following installed: +To request access, join the beta by filling out the [access form](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. Once approved, you will receive an API key via email. -- Install [Bun](https://bun.sh/docs/installation){target=\_blank} +## Construct a Query and Decode the Response -Follow these steps to install the NTT CLI: +Using the Wormhole Query Proxy, you will write a lightweight script to query a token contract's `name()` on Ethereum Sepolia. The response is signed by the Guardian network and locally decoded for use in your application. -1. Run the installation command in your terminal: +1. Create a new directory for your script and initialize a Node.js project: ```bash - curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + mkdir queries + cd queries + npm init -y ``` -2. Verify the NTT CLI is installed: +2. Add the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, [Axios](https://www.npmjs.com/package/axios){target=\_blank}, [Web3](https://www.npmjs.com/package/web3){target=\_blank}, and helper tools: ```bash - ntt --version + npm install axios web3 @wormhole-foundation/wormhole-query-sdk + npm install -D tsx typescript ``` -3. Once installed, check out the available [NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/){target=\_blank} to start using the CLI - -## Update NTT CLI - -To update an existing NTT CLI installation, run the following command in your terminal: - -```bash -ntt update -``` - -NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. +3. Add a new `query.ts` script where you will write and run your query logic: -For local development, you can update your CLI version from a specific branch or install from a local path. + ```bash + touch query.ts + ``` -To install from a specific branch, run: +4. Paste the following script into `query.ts` to build and submit a query to the token contract's `name()` function on Ethereum Sepolia, then decode the Guardian-signed response: -```bash -ntt update --branch foo -``` + ```typescript + // Import the SDK types and helpers for making the query +import { + EthCallQueryRequest, + EthCallQueryResponse, + PerChainQueryRequest, + QueryRequest, + QueryResponse, +} from '@wormhole-foundation/wormhole-query-sdk'; +import axios from 'axios'; +import * as eth from 'web3'; -To install locally, run: -```bash -ntt update --path path/to/ntt/repo -``` +// Define the endpoint and query parameters +const query_url = 'https://testnet.query.wormhole.com/v1/query'; +const rpc = 'https://ethereum-sepolia.rpc.subquery.network/public'; +const chain_id = 10002; // Sepolia (Wormhole chain ID) +const token = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'; // USDC contract +const data = '0x06fdde03'; // function selector for `name()` -Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. +// Load your API key from environment variables +const apiKey = process.env.API_KEY; +if (!apiKey) throw new Error('API_KEY is not set in your environment'); -## Where to Go Next +(async () => { + // Fetch the latest block number (required to anchor the query) + const latestBlock = ( + await axios.post(rpc, { + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 1, + jsonrpc: '2.0', + }) + ).data?.result?.number; -
+ // Build the query targeting the token contract's name() function + const request = new QueryRequest(1, [ + new PerChainQueryRequest( + chain_id, + new EthCallQueryRequest(latestBlock, [{ to: token, data: data }]) + ), + ]); + const serialized = request.serialize(); + // Send the query to the Wormhole Query Proxy + const response = await axios.post( + query_url, + { bytes: Buffer.from(serialized).toString('hex') }, + { headers: { 'X-API-Key': apiKey } } + ); -- :octicons-tools-16:{ .lg .middle } **Deploy to EVM Chains** + // Decode the response returned by the Guardian network + const queryResponse = QueryResponse.from(response.data.bytes); + const chainResponse = queryResponse.responses[0] + .response as EthCallQueryResponse; + const name = eth.eth.abi.decodeParameter('string', chainResponse.results[0]); - --- + // Output the results + console.log('\n\nParsed chain response:'); + console.log(chainResponse); + console.log('\nToken name:', name); +})(); + ``` - Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. +5. Use your API key to execute the script: - [:custom-arrow: Deploy NTT to EVM chains](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/) + ```bash + API_KEY=INSERT_QUERIES_API_KEY npx tsx query.ts + ``` -- :octicons-tools-16:{ .lg .middle } **Deploy to Solana** +The expected output should be similar to this: - --- +
+API_KEY=123_456_789 npx tsx query.ts +Parsed chain response: +EthCallQueryResponse { +blockNumber: 8193548n, +blockHash: '0xef97290e043a530dd2cdf2d4c513397495029cdf2ef3e916746c837dadda51a8', +blockTime: 1745595132000000n, +results: [ '0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000'] +} + +Token name: USDC + +
- Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. +## Next Steps - [:custom-arrow: Deploy NTT to Solana](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/) +Now that you've successfully run your first verifiable query, you are ready to go deeper. Check out the following guides to build on what you've learned: -
+- [**Query Solana**](https://github.com/wormhole-foundation/demo-queries-ts/blob/main/src/query_solana_stake_pool.ts){target=\_blank}: Try fetching Solana stake pools to see how cross-chain queries apply beyond EVM. +- [**Use Queries**](/docs/products/queries/guides/use-queries){target=\_blank}: Take a deeper look at the complete Queries lifecycle. +- **Browse the [Supported Networks](/docs/products/queries/reference/supported-networks){target=\_blank}**: See where Queries are supported. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/ +Doc-Content: https://wormhole.com/docs/products/queries/guides/use-queries/ --- BEGIN CONTENT --- --- -title: Native Token Transfers Post Deployment -description: Learn post-deployment guidelines for optimizing Wormhole NTT, which include testing, security, frontend integration, ecosystem coordination, and monitoring. -categories: NTT, Transfer +title: Use Queries +description: Explore a simple demo of interacting with Wormhole Queries using an eth_call request to query the supply of wETH on Ethereum using a Wormhole query. +categories: Queries --- -# Native Token Transfers Post Deployment +# Use Queries -To offer the best user experience and ensure the most robust deployment, Wormhole contributors recommend the following after you have deployed Native Token Transfers (NTT): +You can visit the [Example Queries Demo](https://wormholelabs-xyz.github.io/example-queries-demo/){target=\_blank} to view an interactive example of an application interacting with the [Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/blob/main/src/QueryDemo.sol){target=\_blank} contract. -- Implement a robust testing plan for your multichain token before launching -- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/build/transfers/native-token-transfers/configuration/){target=\_blank} for more details on ownership and rate limits -- Consider a streamlined, customizable frontend such as [Wormhole Connect](/docs/build/transfers/connect/){target=\_blank} for an optimized user experience -- Alternatively, the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} allows for a direct integration into your infrastructure -- Ensure ecosystem actors such as block explorers, automated security tools (such as BlockAid and Blowfish), and wallets (such as MetaMask, Backpack, and Phantom) are aware of your multichain deployment and that it is labeled appropriately -- Monitor and maintain your multichain deployment +This guide covers using a simple `eth_call` request to get the total supply of WETH on Ethereum. -## Manual Relaying for Solana Transfers +## Construct a Query {: #construct-a-query} -By default, NTT transfers to Solana require manual relaying, meaning that after initiating a cross-chain transfer, the recipient must submit an on-chain transaction to claim the tokens. +You can use the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} to construct a query. You will also need an RPC endpoint from the provider of your choice. This example uses [Axios](https://www.npmjs.com/package/axios){target=\_blank} for RPC requests. Ensure that you also have [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed. -This step ensures that tokens are properly minted or unlocked on Solana and prevents unauthorized claims. +```jsx +npm i @wormhole-foundation/wormhole-query-sdk axios +``` -## Where to Go Next +In order to make an `EthCallQueryRequest`, you need a specific block number or hash as well as the call data to request. -
+You can request the latest block from a public node using `eth_getBlockByNumber`. -- :octicons-code-16:{ .lg .middle } **Wormhole NTT Connect Demo** +```jsx - --- +await axios.post(rpc, { + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 1, + jsonrpc: '2.0', + }) + ).data?.result?.number; +``` - Check out an example project that uses a Vite-React TypeScript application and integrates it with Wormhole Connect, a customizable widget for cross-chain asset transfers. +Then construct the call data. - [:custom-arrow: Explore the NTT Connect demo](https://github.com/wormhole-foundation/demo-ntt-connect) +```jsx +to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH + data: '0x18160ddd', // web3.eth.abi.encodeFunctionSignature("totalSupply()") +}; +``` -- :octicons-code-16:{ .lg .middle } **Wormhole NTT TypeScript SDK Demo** +Finally, put it all together in a `QueryRequest`. - --- +```jsx +const request = new QueryRequest( + 0, // Nonce + [ + new PerChainQueryRequest( + 2, // Ethereum Wormhole Chain ID + new EthCallQueryRequest(latestBlock, [callData]) + ), + ] + ); +``` - Reference an example project that uses the Wormhole TypeScript SDK to facilitate token transfers between different blockchain networks after deploying the NTT framework. +This request consists of one `PerChainQueryRequest`, which is an `EthCallQueryRequest` to Ethereum. You can use `console.log` to print the JSON object and review the structure. - [:custom-arrow: Explore the NTT TypeScript SDK demo](https://github.com/wormhole-foundation/demo-ntt-ts-sdk) +```jsx -
---- END CONTENT --- + // { + // "nonce": 0, + // "requests": [ + // { + // "chainId": 2, + // "query": { + // "callData": [ + // { + // "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + // "data": "0x18160ddd" + // } + // ], + // "blockTag": "0x11e9068" + // } + // } + // ], + // "version": 1 + // } +``` -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/deployment-process/troubleshooting/ ---- BEGIN CONTENT --- ---- -title: Troubleshooting NTT Deployment -description: Resolve common issues in NTT deployment with this troubleshooting guide covering Solana, EVM, mint authority, decimals, and rate limits. -categories: NTT, Transfer ---- +## Mock a Query -# Troubleshooting NTT Deployment +For easier testing, the Query SDK provides a `QueryProxyMock` method. This method will perform the request and sign the result with the [Devnet](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} Guardian key. The `mock` call returns the same format as the Query Proxy. -If you encounter issues during the NTT deployment process, check the following common points: +```jsx +const mockData = await mock.mock(request); + console.log(mockData); + // { + // signatures: ['...'], + // bytes: '...' + // } +``` -- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#install-dependencies){target=\_blank} - - [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** - - [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** -- **Token compliance on EVM** - verify that your token is an ERC20 token on the EVM chain -- **Mint authority transfer** - - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section - - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details -- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#configure-ntt){target=\_blank} section -- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#configure-ntt){target=\_blank} -- **Docker environment based on Ubuntu 20.04 with all dependencies required for Wormhole NTT CLI development** - run `docker compose up -d` to start the container in your terminal from the directory containing the `docker-compose.yml` file +This response is suited for on-chain use, but the SDK also includes a parser to make the results readable via the client. - ???- interface "Dockerfile" +```jsx +const mockQueryResult = ( + mockQueryResponse.responses[0].response as EthCallQueryResponse + ).results[0]; + console.log( + `Mock Query Result: ${mockQueryResult} (${BigInt(mockQueryResult)})` + ); + // Mock Query Result: + // 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee + // (3172556167631284394053614) +``` - ```Dockerfile - FROM ubuntu:20.04 - # Set environment variables to prevent interactive prompts during installation - ENV DEBIAN_FRONTEND=noninteractive - - # Update and install necessary dependencies - RUN apt-get update && apt-get install -y \ - curl \ - wget \ - git \ - build-essential \ - libssl-dev \ - libudev-dev \ - pkg-config \ - python3 \ - python3-pip \ - software-properties-common \ - ca-certificates \ - unzip \ - clang \ - cmake \ - protobuf-compiler \ - && apt-get clean && rm -rf /var/lib/apt/lists/* - - # Install Rust - RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - ENV PATH="/root/.cargo/bin:$PATH" - - # Install Solana CLI ({{ntt.solana_cli_version}}) - RUN sh -c "$(curl -sSfL https://release.solana.com/{{ntt.solana_cli_version}}/install)" - ENV PATH="/root/.local/share/solana/install/active_release/bin:$PATH" +Testing this all together might look like the following: - # Install Anchor using avm - RUN cargo install --git https://github.com/coral-xyz/anchor avm --locked --force \ - && avm install 0.29.0 \ - && avm use 0.29.0 - ENV PATH="/root/.avm/bin:$PATH" +```jsx +import { + EthCallData, + EthCallQueryRequest, + EthCallQueryResponse, + PerChainQueryRequest, + QueryProxyMock, + QueryRequest, + QueryResponse, +} from '@wormhole-foundation/wormhole-query-sdk'; +import axios from 'axios'; +const rpc = 'https://ethereum.publicnode.com'; +const callData: EthCallData = { + to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH + data: '0x18160ddd', // web3.eth.abi.encodeFunctionSignature("totalSupply()") +}; - ENV NVM_DIR=/root/.nvm - RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \ - && . "$NVM_DIR/nvm.sh" \ - && nvm install 22 \ - && nvm use 22 \ - && nvm alias default 22 - ENV PATH="$NVM_DIR/versions/node/v22.12.0/bin:$PATH" +(async () => { + const latestBlock: string = ( + await axios.post(rpc, { + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 1, + jsonrpc: '2.0', + }) + ).data?.result?.number; + if (!latestBlock) { + console.error(`❌ Invalid block returned`); + return; + } + console.log('Latest Block: ', latestBlock, `(${BigInt(latestBlock)})`); + const targetResponse = await axios.post(rpc, { + method: 'eth_call', + params: [callData, latestBlock], + id: 1, + jsonrpc: '2.0', + }); + // console.log(finalizedResponse.data); + if (targetResponse.data.error) { + console.error(`❌ ${targetResponse.data.error.message}`); + } + const targetResult = targetResponse.data?.result; + console.log('Target Result: ', targetResult, `(${BigInt(targetResult)})`); + // Form the query request + const request = new QueryRequest( + 0, // Nonce + [ + new PerChainQueryRequest( + 2, // Ethereum Wormhole Chain ID + new EthCallQueryRequest(latestBlock, [callData]) + ), + ] + ); + console.log(JSON.stringify(request, undefined, 2)); + const mock = new QueryProxyMock({ 2: rpc }); + const mockData = await mock.mock(request); + console.log(mockData); + const mockQueryResponse = QueryResponse.from(mockData.bytes); + const mockQueryResult = ( + mockQueryResponse.responses[0].response as EthCallQueryResponse + ).results[0]; + console.log( + `Mock Query Result: ${mockQueryResult} (${BigInt(mockQueryResult)})` + ); +})(); +``` - # Install Bun - RUN curl -fsSL https://bun.sh/install | bash - ENV PATH="/root/.bun/bin:$PATH" +### Fork Testing - # Install Foundry - RUN curl -L https://foundry.paradigm.xyz | bash - ENV PATH="/root/.foundry/bin:${PATH}" - RUN /bin/bash -c "source /root/.bashrc && foundryup" +It is common to test against a local fork of Mainnet with something like - # Install Wormhole NTT CLI - RUN curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash +```jsx +anvil --fork-url https://ethereum.publicnode.com +``` - # Add a default working directory - WORKDIR /app +In order for mock requests to verify against the Mainnet Core Contract, you need to replace the current Guardian set with the single Devnet key used by the mock. - # Expose port for development if needed - EXPOSE 8899 +Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. - # Entry point for the container - CMD ["bash"] - ``` +```jsx +npx @wormhole-foundation/wormhole-cli evm hijack -a 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B -g 0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe +``` - ???- interface "docker-compose.yml" - ```yml - services: - portal-ntt: - build: - context: . - dockerfile: Dockerfile - platform: linux/amd64 - volumes: - - ./src:/app - working_dir: /app - tty: true - ``` ---- END CONTENT --- +If you are using `EthCallWithFinality`, you will need to mine additional blocks (32 if using [Anvil](https://book.getfoundry.sh/anvil/){target=\_blank}) after the latest transaction for it to become finalized. Anvil supports [auto-mining](https://book.getfoundry.sh/reference/anvil/#mining-modes){target=\_blank} with the `-b` flag if you want to test code that waits naturally for the chain to advance. For integration tests, you may want to simply `anvil_mine` with `0x20`. -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/faqs/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers FAQs -description: Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. -categories: NTT, Transfer ---- +## Make a Query Request -# Wormhole NTT FAQs +The standardized means of making a `QueryRequest` with an API key is as follows: -## Do you have an example of how cross-chain lending can be implemented using Wormhole? +```jsx +const serialized = request.serialize(); +const proxyResponse = + (await axios.post) < + QueryProxyQueryResponse > + (QUERY_URL, + { + bytes: Buffer.from(serialized).toString("hex"), + }, + { headers: { "X-API-Key": YOUR_API_KEY } }); +``` -Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. +Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. -Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/learn/transfers/native-token-transfers/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. +A Testnet Query Proxy is available at `https://testnet.query.wormhole.com/v1/query` -## What causes the "No protocols registered for Evm" error in Wormhole SDK? +A Mainnet Query Proxy is available at `https://query.wormhole.com/v1/query` -This error typically occurs when the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} cannot recognize or register the necessary EVM protocols, which are required for interacting with Ethereum-based networks. The most common reason for this error is that the relevant EVM package for Wormhole's NTT has not been imported correctly. +## Verify a Query Response On-Chain -To resolve this issue, ensure you have imported the appropriate Wormhole SDK package for EVM environments. The necessary package for handling NTT on EVM chains is `@wormhole-foundation/sdk-evm-ntt`. Here's the correct import statement: +A [`QueryResponseLib` library](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/QueryResponse.sol){target=\_blank} is provided to assist with verifying query responses. You can begin by installing the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} with the following command: -```rust -import '@wormhole-foundation/sdk-evm-ntt'; +```bash +forge install wormhole-foundation/wormhole-solidity-sdk ``` -By importing this package, the Wormhole SDK can register and utilize the required protocols for EVM chains, enabling cross-chain token transfers using the NTT framework. Ensure to include this import at the start of your code, especially before attempting any interactions with EVM chains in your project. +Broadly, using a query response on-chain comes down to three main steps: -## How can I transfer ownership of NTT to a multisig? + 1. Parse and verify the query response + 2. The `parseAndVerifyQueryResponse` handles verifying the Guardian signatures against the current Guardian set stored in the Core bridge contract + 3. Validate the request details. This may be different for every integrator depending on their use case, but generally checks the following: + - Is the request against the expected chain? + - Is the request of the expected type? The `parseEthCall` helpers perform this check when parsing + - Is the resulting block number and time expected? Some consumers might require that a block number be higher than the last, or the block time be within the last 5 minutes. `validateBlockNum` and `validateBlockTime` can help with the checks + - Is the request for the expected contract and function signature? The `validateMultipleEthCallData` can help with non-parameter-dependent cases + - Is the result of the expected length for the expected result type? + 4. Run `abi.decode` on the result -Transferring ownership of Wormhole's NTT to a multisig is a two-step process for safety. This ensures that ownership is not transferred to an address that cannot claim it. Refer to the `transfer_ownership` method in the [NTT Manager Contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/programs/example-native-token-transfers/src/instructions/admin/transfer_ownership.rs#L55){target=\_blank} to initiate the transfer. +See the [QueryDemo](https://github.com/wormholelabs-xyz/example-queries-demo/blob/main/src/QueryDemo.sol){target=\_blank} contract for an example and read the docstrings of the preceding methods for detailed usage instructions. -1. **Initiate transfer** - use the `transfer_ownership` method on the NTT Manager contract to set the new owner (the multisig) -2. **Claim ownership** - the multisig must then claim ownership via the `claim_ownership` instruction. If not claimed, the current owner can cancel the transfer -3. **Single-step transfer (Riskier)** - you can also use the `transfer_ownership_one_step_unchecked` method to transfer ownership in a single step, but if the new owner cannot sign, the contract may become locked. Be cautious and ensure the new owner is a Program Derived Address (PDA) +??? code "View the complete `QueryDemo`" + ```solidity + // contracts/query/QueryDemo.sol +// SPDX-License-Identifier: Apache 2 -For a practical demonstration of transferring ownership of Wormhole's NTT to a multisig on Solana, visit the [GitHub demo](https://github.com/wormhole-foundation/demo-ntt-solana-multisig-tools){target=\_blank} providing scripts and guidance for managing an NTT program using Squads multisig functionality, including ownership transfer procedures. +pragma solidity ^0.8.0; -## How can I specify a custom RPC for NTT? +import "wormhole-solidity-sdk/libraries/BytesParsing.sol"; +import "wormhole-solidity-sdk/interfaces/IWormhole.sol"; +import "wormhole-solidity-sdk/QueryResponse.sol"; -To specify a custom RPC for Wormhole's NTT, create an `overrides.json` file in the root of your deployment directory. This file allows you to define custom RPC endpoints, which can be helpful when you need to connect to specific nodes or networks for better performance, security, or control over the RPC connection. +error InvalidOwner(); +// @dev for the onlyOwner modifier +error InvalidCaller(); +error InvalidCalldata(); +error InvalidForeignChainID(); +error ObsoleteUpdate(); +error StaleUpdate(); +error UnexpectedResultLength(); +error UnexpectedResultMismatch(); -Below’s an example of how the `overrides.json` file should be structured: +/// @dev QueryDemo is an example of using the QueryResponse library to parse and verify Cross Chain Query (CCQ) responses. +contract QueryDemo is QueryResponse { + using BytesParsing for bytes; -???- code "`overrides.json`" - ```json - { - "chains": { - "Bsc": { - "rpc": "http://127.0.0.1:8545" - }, - "Sepolia": { - "rpc": "http://127.0.0.1:8546" - }, - "Solana": { - "rpc": "http://127.0.0.1:8899" - } - } + struct ChainEntry { + uint16 chainID; + address contractAddress; + uint256 counter; + uint256 blockNum; + uint256 blockTime; } - ``` -## How can I redeem tokens if NTT rate limits block them on the target chain? + address private immutable owner; + uint16 private immutable myChainID; + mapping(uint16 => ChainEntry) private counters; + uint16[] private foreignChainIDs; -If the rate limits on Wormhole's NTT block tokens from being received on the target chain, the transaction will typically be paused until the rate limits are adjusted. Rate limits are implemented to manage congestion and prevent chain abuse, but they can occasionally delay token redemptions. + bytes4 public GetMyCounter = bytes4(hex"916d5743"); -To resolve this: + constructor(address _owner, address _wormhole, uint16 _myChainID) QueryResponse(_wormhole) { + if (_owner == address(0)) { + revert InvalidOwner(); + } + owner = _owner; -1. **Adjust rate limits** - the rate limits must be modified by an administrator or through the appropriate configuration tools to allow the blocked transaction to proceed -2. **Resume transaction flow** - once the rate limits are adjusted, you can resume the flow, which should be visible in the UI. The tokens will then be redeemable on the target chain + myChainID = _myChainID; + counters[_myChainID] = ChainEntry(_myChainID, address(this), 0, 0, 0); + } -In most cases, the transaction will resume automatically once the rate limits are adjusted, and the UI will guide you through the redemption process. - -## What are the challenges of deploying NTT to non-EVM chains? - -NTT requires the same transceiver for all routes, limiting flexibility when deploying across EVM and non-EVM chains. For example, if you're deploying to Ethereum, Arbitrum, and Solana, you can't use Wormhole and Axelar as transceivers because Axelar doesn't support Solana. This constraint forces integrators to use a single transceiver (e.g., Wormhole) for all chains, reducing flexibility in optimizing cross-chain transfers. - -## Does the NTT manager function as an escrow account for a hub chain? - -Yes, the NTT manager acts like an escrow account for non-transferable tokens on a hub chain. To manage non-transferable tokens, you would add the NTT manager to the allowlist, ensuring that only the NTT manager can hold and control the tokens as they are transferred across chains. - -## Which functions or events does Connect rely on for NTT integration? - -Connect relies on the NTT SDK for integration, with platform-specific implementations for both [Solana](https://github.com/wormhole-foundation/native-token-transfers/blob/main/solana/ts/sdk/ntt.ts){target=\_blank} and [EVM](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/ts/src/ntt.ts){target=\_blank}. The key methods involved include: - -- **Initiate and redeem functions** - these functions are essential for initiating token transfers and redeeming them on the destination chain -- **Rate capacity methods** - methods for fetching inbound and outbound rate limits are also critical for controlling the flow of tokens and preventing congestion + // updateRegistration should be used to add the other chains and to set / update contract addresses. + function updateRegistration(uint16 _chainID, address _contractAddress) public onlyOwner { + if (counters[_chainID].chainID == 0) { + foreignChainIDs.push(_chainID); + counters[_chainID].chainID = _chainID; + } -These functions ensure Connect can handle token transfers and manage chain-rate limits. + counters[_chainID].contractAddress = _contractAddress; + } -## How does the relayer contract determine which transceiver to call? + // getMyCounter (call signature 916d5743) returns the counter value for this chain. It is meant to be used in a cross chain query. + function getMyCounter() public view returns (uint256) { + return counters[myChainID].counter; + } -The source chain's transceiver includes the destination chain's transceiver in the message via the relayer contract. The admin configures each transceiver's mapping of its peers on other chains. This mapping allows the destination transceiver to verify that the message came from a trusted source. + // getState() returns this chain's view of all the counters. It is meant to be used in the front end. + function getState() public view returns (ChainEntry[] memory) { + ChainEntry[] memory ret = new ChainEntry[](foreignChainIDs.length + 1); + ret[0] = counters[myChainID]; + uint256 length = foreignChainIDs.length; -## How do I create a verifier or transceiver? + for (uint256 i = 0; i < length;) { + ret[i + 1] = counters[foreignChainIDs[i]]; + unchecked { + ++i; + } + } -To run your verifier, you need to implement a transceiver. This involves approximately 200 lines of code, leveraging the base functionality provided by the [abstract transceiver contract](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/Transceiver/Transceiver.sol){target=\_blank}. + return ret; + } -For reference, you can review the [Axelar transceiver implementation](https://github.com/wormhole-foundation/example-wormhole-axelar-wsteth/blob/main/src/axelar/AxelarTransceiver.sol){target=\_blank}. + // @notice Takes the cross chain query response for the other counters, stores the results for the other chains, and updates the counter for this chain. + function updateCounters(bytes memory response, IWormhole.Signature[] memory signatures) public { + ParsedQueryResponse memory r = parseAndVerifyQueryResponse(response, signatures); + uint256 numResponses = r.responses.length; + if (numResponses != foreignChainIDs.length) { + revert UnexpectedResultLength(); + } -## Can I use Hetzner for the NTT deployment? + for (uint256 i = 0; i < numResponses;) { + // Create a storage pointer for frequently read and updated data stored on the blockchain + ChainEntry storage chainEntry = counters[r.responses[i].chainId]; + if (chainEntry.chainID != foreignChainIDs[i]) { + revert InvalidForeignChainID(); + } -No, using Hetzner servers for Solana deployments is not recommended. Hetzner has blocked Solana network activity on its servers, leading to connection issues. Hetzner nodes will return a `ConnectionRefused: Unable to connect` error for Solana deployments. Therefore, choosing alternative hosting providers that support Solana deployments is advisable to ensure seamless operation. + EthCallQueryResponse memory eqr = parseEthCallQueryResponse(r.responses[i]); -## How can I transfer tokens with NTT with an additional payload? + // Validate that update is not obsolete + validateBlockNum(eqr.blockNum, chainEntry.blockNum); -You can include an extra payload in NTT messages by overriding specific methods in the [NttManager contract](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol){target=\_blank}. + // Validate that update is not stale + validateBlockTime(eqr.blockTime, block.timestamp - 300); -- On the source chain, override the [`_handleMsg` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L216-L226){target=\_blank} to query any additional data you need for the transfer. The extra payload can then be added to the message -- On the destination chain override the [`_handleAdditionalPayload` function](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/evm/src/NttManager/NttManager.sol#L262-L275){target=\_blank} to process and utilize the extra payload sent in the message + if (eqr.result.length != 1) { + revert UnexpectedResultMismatch(); + } -!!!Important - You cannot pass the additional data as part of the entry point directly. Instead, the data must be queried on-chain via the `_handleMsg` method, ensuring the payload is properly included and processed. + // Validate addresses and function signatures + address[] memory validAddresses = new address[](1); + bytes4[] memory validFunctionSignatures = new bytes4[](1); + validAddresses[0] = chainEntry.contractAddress; + validFunctionSignatures[0] = GetMyCounter; -## Why use NTT over xERC20? + validateMultipleEthCallData(eqr.result, validAddresses, validFunctionSignatures); -Shortcomings of xERC20: + require(eqr.result[0].result.length == 32, "result is not a uint256"); -- **Single point of failure** - xERC20 relies on multiple bridges, but a compromise in any single bridge can jeopardize the token. It enforces a 1-of-n design rather than a more robust m-of-n approach -- **No pausing** - xERC20 lacks mechanisms to pause operations during emergencies -- **No access control** - there are no built-in access controls for managing token transfers securely -- **Limited rate limiting** - rate limits are bridge-specific and cannot be set per chain, reducing flexibility and security -- **No integration with relaying systems** - xERC20 does not natively support relayer systems, limiting its usability in automated or dynamic setups + chainEntry.blockNum = eqr.blockNum; + chainEntry.blockTime = eqr.blockTime / 1_000_000; + chainEntry.counter = abi.decode(eqr.result[0].result, (uint256)); -While xERC20 is an extension of the ERC20 standard, NTT is designed as a framework rather than a rigid standard. It is compatible with any token that supports `burn` and `mint` functions and allows the NTT manager to act as a minter. + unchecked { + ++i; + } + } -## How can I start transferring tokens to a chain that is in burning mode, if no tokens are locked yet? + counters[myChainID].blockNum = block.number; + counters[myChainID].blockTime = block.timestamp; + counters[myChainID].counter += 1; + } -To begin transferring tokens to a chain in burning mode when no tokens are locked, you must first send tokens to the NTT manager to back the supply. The address of the NTT manager can be found in the `deployment.json` file. + modifier onlyOwner() { + if (owner != msg.sender) { + revert InvalidOwner(); + } + _; + } +} + ``` -## Is there a way to use NTT tokens with chains that don't currently support NTT? +## Submit a Query Response On-Chain -Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. For example: +The `QueryProxyQueryResponse` result requires a slight tweak when submitting to the contract to match the format of `function parseAndVerifyQueryResponse(bytes memory response, IWormhole.Signature[] memory signatures)`. A helper function, `signaturesToEvmStruct`, is provided in the SDK for this. -- **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) -- **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism -- **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT +This example submits the transaction to the demo contract: -This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. +```jsx +const tx = await contract.updateCounters( + `0x${response.data.bytes}`, + signaturesToEvmStruct(response.data.signatures) +); +``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/ +Doc-Content: https://wormhole.com/docs/products/queries/overview/ --- BEGIN CONTENT --- --- -title: Native Token Transfers (NTT) -description: This section provides comprehensive guidance on configuring, deploying, and managing your Native Token Transfers (NTT) integration. -categories: NTT, Transfer +title: Queries Overview +description: Learn how Wormhole Queries enable smart contracts to fetch real-time, Guardian-verified data across multiple blockchains. +categories: Queries --- -# Native Token Transfers +# Queries Overview -Native Token Transfers (NTT) simplifies and enables seamless, flexible token transfers across blockchains. This section provides comprehensive guidance on configuring, deploying, and managing your NTT integration. It includes information relevant to both new token deployments and existing token management. +Queries provide on-demand access to Guardian-attested on-chain data. They allow smart contracts to fetch real-time, verifiable data from across the multichain ecosystem, such as prices, rates, and liquidity. -Visit the [Use Cases](/docs/build/start-building/use-cases/){target=\_blank} and [Product Comparison](/docs/build/start-building/products/){target=\_blank} pages for help determining if NTT will meet the needs of your project. +## Key Features -## Quickstart +- **On-demand data access**: Fetch price feeds, interest rates, and other data in real-time. +- **Guardian attested**: All data is signed by [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} for trustless validation. +- **Cross-chain ready**: Request data on one chain, use it on another. +- **Smart contract integration**: Results are delivered as [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank}, readable by smart contracts. +- **Chain agnostic**: works across supported EVM chains, Solana, Sui, and [more](/docs/products/queries/reference/supported-networks/){target=\_blank}. -If needed, you can generate test tokens for development with the [`example-ntt-token`](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} GitHub repository by following the README instructions. +## How It Works -The process for creating, deploying, and monitoring NTTs is as follows. Select the title of each step to view the associated guide: +A query request follows a simple but robust lifecycle. The off-chain service responsible for handling requests is called the CCQ Server (Cross-Chain Query Server), also referred to as the Query Server throughout this documentation. -[timeline left(wormhole-docs/.snippets/text/build/transfers/ntt/ntt-deployment-process-timeline.json)] +1. An off-chain app sends a query to the CCQ Server via HTTPS +2. The CCQ Server checks the request and shares it with [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} +3. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} independently fetch the data, verify it, and sign the result +4. Once enough Guardians (2/3 quorum) return matching results, the CCQ Server aggregates and sends the final response +5. The off-chain app submits this result to a smart contract, which verifies the Guardian signatures and uses the data -## Deploy NTTs with Launchpad +The CCQ Server is permissioned but trustless. Most queries resolve in under one second, and Guardians retry failed requests for up to one minute. Up to 255 queries can be batched together to optimize performance, supporting efficient multichain workflows. -If you are deploying to EVM blockchains, the [Native Token Transfers (NTT) Launchpad](https://ntt.wormhole.com/){target=\_blank} is a Wormhole-managed UI application that provides a step-by-step interface for deploying NTT. NTT Launchpad replaces manually deploying contracts or configuring relayers for each supported EVM chain. +![The architecture flow of a query](/docs/images/products/queries/overview/overview-1.webp) -Follow the [Deploy NTT with Launchpad](/docs/build/transfers/native-token-transfers/deployment-process/evm-launchpad/){target=\_blank} guide to create new multichain tokens or integrate existing tokens with just a few clicks. +## Use Cases -## Additional Resources +Queries enable a wide range of cross-chain applications. Below are common use cases and the Wormhole stack components you can use to build them. -
+- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** -- :octicons-gear-16:{ .lg .middle } **NTT CLI Commands** + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch rates and prices in real-time. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Sync actions between chains. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. - --- +- **Cross-Chain Swaps and Liquidity Aggregation (e.g., [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank})** - The NTT CLI tool provides a comprehensive set of commands for creating, configuring, deploying, and monitoring NTTs. This page provides a comprehensive list of available NTT CLI commands, their descriptions, and examples to help you interact effectively with the NTT system. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch live prices optimal trade execution. + - [**Connect**](/docs/products/connect/overview/){target=\_blank}: Handle user-friendly asset transfers. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Moves native tokens. - [:custom-arrow: NTT CLI Commands](/docs/build/transfers/native-token-transfers/cli-commands/) +- **Real-Time Price Feeds and Trading Strategies (e.g., [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank})** -- :octicons-question-16:{ .lg .middle } **NTT FAQs** + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch price feeds. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Trigger trades. - --- +- **Multichain Prediction Markets** - Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch market data and odds. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Automates token execution. - [:custom-arrow: Check out the FAQs](/docs/build/transfers/native-token-transfers/faqs/) +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** -
+ - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Source data from chains. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Ensures tamper-proof data relay across networks. + +## Next Steps + +Follow these steps to get started with Queries: + +[timeline(wormhole-docs/.snippets/text/products/queries/queries-timeline.json)] --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/native-token-transfers/managers-transceivers/ +Doc-Content: https://wormhole.com/docs/products/queries/reference/supported-methods/ --- BEGIN CONTENT --- --- -title: Managers and Transceivers -description: Explore the roles of Managers and Transceivers in NTT cross-chain token transfers, including key functions, lifecycle events, and rate-limiting mechanisms. -categories: NTT, Transfer +title: Queries Supported Methods +description: Retrieve multichain data via historical timestamp queries, finality confirmation queries, and Solana lookups. +categories: Queries --- -# Managers and Transceivers - -## Managers - -_Managers_ oversee the token transfer process and handle rate-limiting and message attestation. They manage interactions with multiple transceivers and ensure that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. Each NTT manager corresponds to a single token but can control multiple transceivers. Key functions include: - -- **`transfer`** - initiate the transfer process where tokens on the source chain are locked or burned. This process ensures that an equivalent amount of tokens can be minted or unlocked on the destination chain +# Supported Methods - ```solidity - function transfer( - uint256 amount, // amount (in atomic units) - uint16 recipientChain, // chain ID (Wormhole formatted) - bytes32 recipient // recipient address (Wormhole formatted) - ) external payable nonReentrant whenNotPaused returns (uint64) - ``` +Wormhole Queries provides on-demand access to [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}-attested on-chain data through a simple REST endpoint. It offers a faster, gasless alternative to traditional transaction-based data retrieval, removing the need for gas fees and transaction finality delays. Requests are handled off-chain and processed by the Guardians, delivering verified data efficiently and cost-effectively. -- **`quoteDeliveryPrice`** - calculate the cost of sending messages across chains by querying the transceivers for estimates on message delivery fees, allowing users to know the price before initiating a transfer +This page describes Wormhole Queries, their functionality, and available methods, aiming to assist new developers in utilizing the service. - ```solidity - function quoteDeliveryPrice( - uint16 recipientChain, // chain ID (Wormhole formatted) - bytes memory transceiverInstructions // extra instructions for transceivers (Transceiver-dependent on whether extra instructions are used/accepted) - ) public view returns (uint256[] memory, uint256) - ``` +## Supported Query Types -- **`setPeer`** - to maintain secure cross-chain communication, managers establish trust relationships between different instances of NTT manager contracts across chains. By recognizing each other as peers, they ensure that the token transfers happen securely and that rate limits on inbound transactions are respected +Wormhole currently supports five distinct query types, each designed for specific data retrieval tasks across various chains. - ```solidity - function setPeer( - uint16 peerChainId, // chain ID (Wormhole formatted) - bytes32 peerContract, // peer NTT Manager address (Wormhole formatted) - uint8 decimals, // token decimals on the peer chain - uint256 inboundLimit // inbound rate limit (in atomic units) - ) public onlyOwner - ``` +!!! note + For a more comprehensive technical description and further specifics on each query type, please consult the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md). -## Transceivers -_Transceivers_ are responsible for routing NTT transfers through the manager on the source chain and ensuring they are delivered to the corresponding manager on the recipient chain. They work with managers to ensure that messages are accurately processed and tokens are correctly transferred, providing a reliable system for cross-chain token transfers. Transceivers can be defined independently of the Wormhole core and modified to support any verification backend. Key functions: +### eth_call -- **`sendMessage`** - this external function sends token transfer messages to a specified recipient chain. It encodes the token transfer details into a message format recognized by the system +The [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} query type allows you to perform read-only calls to a smart contract on a specific block, identified by its number or hash. Some of eth_call's configurations include: - ```solidity - function sendMessage( - uint16 recipientChain, // chain ID (Wormhole formatted) - TransceiverStructs.TransceiverInstruction memory instruction, // extra instruction for the Transceiver (optional, dependent on whether extra instructions are used/accepted for this Transceiver) - bytes memory nttManagerMessage, // serialized NTT Manager message, provided by the NTT Manager - bytes32 recipientNttManagerAddress, // NTT Manager address on the recipient chain (Wormhole formatted) - bytes32 refundAddress // address to receive refunds on the destination chain in case of excess quotes (Wormhole formatted) - ) external payable nonReentrant onlyNttManager - ``` +- **Batching** - group multiple calls, even to different contracts, into a single query targeting the same block, which is processed as one batch RPC call to simplify on-chain verification +- **Capacity** - batch up to 255 individual in a single eth_call query +- **Result data** - provides the specified block's number, hash, timestamp, and the output from the contract call -- **`quoteDeliveryPrice`** - provides an estimation of the cost associated with delivering a message to a target chain and gauges transaction fees +### eth_call_by_timestamp - ```solidity - function quoteDeliveryPrice( - uint16 targetChain, // chain ID (Wormhole formatted) - TransceiverStructs.TransceiverInstruction memory instruction // extra instruction for the Transceiver (optional, dependent on whether extra instructions are used/accepted for this Transceiver) - ) external view returns (uint256) - ``` +The [`eth_call_by_timestamp`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#timestamp-and-block-id-hints-in-eth_call_by_timestamp){target=\_blank} query is similar to a standard `eth_call` but targets a specific timestamp instead of a block ID. This is useful for retrieving on-chain data based on a precise point in time, especially for correlating information across different chains. -## Lifecycle of a Message +The query returns your target timestamp and the latest block details at or before your specified `target_time` immediately preceding the subsequent block. -### EVM +### eth_call_with_finality -#### Transfer +The [`eth_call_with_finality`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#desired-finality-in-eth_call_with_finality){target=\_blank} query type functions like a standard `eth_call`, but with an added critical assurance: it will only return the query results once the specified block has reached a designated level of finality on its chain. -A client calls on `transfer` to initiate an NTT transfer. The client must specify, at minimum, the transfer amount, the recipient chain, and the recipient address on the recipient chain. `transfer` also supports a flag to specify whether the `NttManager` should queue rate-limited transfers or revert. Clients can also include additional instructions to forward along to the transceiver on the source chain. Depending on the mode set in the initial configuration of the `NttManager` contract, transfers are either "locked" or "burned." Once the transfer has been forwarded to the transceiver, the `NttManager` emits the `TransferSent` event. +You can specify one of two finality levels for your query: -**Events** +- **Finalized** - indicates the highest level of assurance that a block is permanent and will not be altered or removed from the chain +- **Safe** - refers to a block considered highly unlikely to be reorganized, offering a substantial degree of confidence, though the network's consensus may not fully finalize it -```ts -/// @notice Emitted when a message is sent from the nttManager. -/// @dev Topic0 -/// 0x9716fe52fe4e02cf924ae28f19f5748ef59877c6496041b986fbad3dae6a8ecf -/// @param recipient The recipient of the message. -/// @param amount The amount transferred. -/// @param fee The amount of ether sent along with the tx to cover the delivery fee. -/// @param recipientChain The chain ID of the recipient. -/// @param msgSequence The unique sequence ID of the message. -event TransferSent( - bytes32 recipient, uint256 amount, uint256 fee, uint16 recipientChain, uint64 msgSequence -); -``` +!!! note + If the target blockchain does not natively support or recognize the safe finality tag, requesting safe finality will be treated as a request for finalized finality instead. -#### Rate Limit +### sol_account -A transfer can be rate-limited on both the source and destination chains. If a transfer is rate-limited on the source chain and the `shouldQueue` flag is enabled, it is added to an outbound queue. The transfer can be released after the configured `_rateLimitDuration` has expired via the `completeOutboundQueuedTransfer` method. The `OutboundTransferQueued` and `OutboundTransferRateLimited` events are emitted. +The [`sol_account`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana-queries){target=\_blank} query reads on-chain data for one or more specified accounts on the Solana blockchain. This functionality is similar to using Solana's native [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} RPC method, enabling you to retrieve information for multiple accounts simultaneously -If the client attempts to release the transfer from the queue before the expiry of the `rateLimitDuration`, the contract reverts with an `OutboundQueuedTransferStillQueued` error. +### sol_pda -Similarly, rate-limited transfers on the destination chain are added to an inbound queue. These transfers can be released from the queue via the `completeInboundQueuedTransfer` method, and the `InboundTransferQueued` event is emitted. +The [`sol_pda`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana_queries){target=\_blank} query reads data for one or more Solana [Program Derived Addresses](https://www.anchor-lang.com/docs/pdas){target=\_blank}. It streamlines the standard process of deriving a PDA and fetching its account data. -If the client attempts to release the transfer from the queue before the `rateLimitDuration` expires, the contract reverts with an `InboundQueuedTransferStillQueued` error. +This is particularly useful for accessing multiple PDAs owned by a specific program or for verifying Solana PDA derivations on another blockchain, such as how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. +--- END CONTENT --- -To deactivate the rate limiter, set `_rateLimitDuration` to 0 and enable the `_skipRateLimiting` field in the `NttManager` constructor. Configuring this incorrectly will throw an error. If the rate limiter is deactivated, the inbound and outbound rate limits can be set to 0. +Doc-Content: https://wormhole.com/docs/products/queries/reference/supported-networks/ +--- BEGIN CONTENT --- +--- +title: Queries Supported Networks +description: Reference table of chains supported by Wormhole Queries, including method support, finality, and expected historical data availability. +categories: Queries +--- -**Events** +# Supported Networks -```ts -/// @notice Emitted whenn an outbound transfer is queued. -/// @dev Topic0 -/// 0x69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f. -/// @param queueSequence The location of the transfer in the queue. -event OutboundTransferQueued(uint64 queueSequence); -``` +This page provides a quick reference for chains supported by Wormhole Queries, including each chain's Wormhole chain ID and the level of support for key methods: [`eth_call`](/docs/products/queries/reference/supported-methods/#eth_call){target=\_blank}, [`eth_call_by_timestamp`](/docs/products/queries/reference/supported-methods/#eth_call_by_timestamp){target=\_blank}, and [`eth_call_with_finality`](/docs/products/queries/reference/supported-methods/#eth_call_with_finality){target=\_blank}. -```ts -/// @notice Emitted when an outbound transfer is rate limited. -/// @dev Topic0 -/// 0x754d657d1363ee47d967b415652b739bfe96d5729ccf2f26625dcdbc147db68b. -/// @param sender The initial sender of the transfer. -/// @param amount The amount to be transferred. -/// @param currentCapacity The capacity left for transfers within the 24-hour window. -event OutboundTransferRateLimited( - address indexed sender, uint64 sequence, uint256 amount, uint256 currentCapacity -); -``` +The **Expected History** column shows how much recent state data is typically available for querying, though this can vary depending on the chain and the configuration of each Guardian node. -```ts -/// @notice Emitted when an inbound transfer is queued -/// @dev Topic0 -/// 0x7f63c9251d82a933210c2b6d0b0f116252c3c116788120e64e8e8215df6f3162. -/// @param digest The digest of the message. -event InboundTransferQueued(bytes32 digest); -``` +The support shown in the table reflects what has been confirmed through testing. However, query success ultimately depends on whether the underlying call can be executed on each Guardian’s RPC node. -#### Send +For example, many chains use a fork of [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which by default retains 128 blocks of state in memory (unless archive mode is enabled). On Ethereum mainnet, this covers around 25 minutes of history—but on faster chains like Optimism, it may span only about three minutes. While Guardian nodes are expected to have access to recent state, there are currently no guarantees on how far back historical data is available. -Once the `NttManager` forwards the message to the transceiver, the message is transmitted via the `sendMessage method`. The method signature is enforced by the transceiver but transceivers are free to determine their own implementation for transmitting messages. (e.g. a message routed through the Wormhole transceiver can be sent via Wormhole relaying, a custom relayer, or manually published via the core bridge). +## Mainnet -Once the message has been transmitted, the contract emits the `SendTransceiverMessage` event. +| Chain | Wormhole Chain ID | eth_call | eth_call_by_timestamp | eth_call_with_finality | Expected History | +|:-------------:|:-----------------:|:--------:|:---------------------:|:----------------------:|:----------------:| +| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | +| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | +| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | +| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | +| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | +| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | +| Karura | 11 | ✅ | ✅ | ✅ | archive | +| Acala | 12 | ✅ | ✅ | ✅ | archive | +| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | +| Celo | 14 | ✅ | ℹ️ | ✅ | 128 blocks | +| Moonbeam | 16 | ✅ | ℹ️ | ✅ | 256 blocks | +| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | +| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | +| Base | 30 | ✅ | ✅ | ✅ | archive | -**Events** +ℹ️`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. +--- END CONTENT --- -```ts -/// @notice Emitted when a message is sent from the transceiver. -/// @dev Topic0 -/// 0x53b3e029c5ead7bffc739118953883859d30b1aaa086e0dca4d0a1c99cd9c3f5. -/// @param recipientChain The chain ID of the recipient. -/// @param message The message. -event SendTransceiverMessage( - uint16 recipientChain, TransceiverStructs.TransceiverMessage message -); -``` - -#### Receive - -Once a message has been emitted by a transceiver on the source chain, an off-chain process (for example, a relayer) will forward the message to the corresponding transceiver on the recipient chain. The relayer interacts with the transceiver via an entry point to receive messages. For example, the relayer will call the `receiveWormholeMessage` method on the `WormholeTransceiver` contract to execute the message. The `ReceiveRelayedMessage` event is emitted during this process. - -This method should also forward the message to the `NttManager` on the destination chain. Note that the transceiver interface doesn't declare a signature for this method because receiving messages is specific to each transceiver, and a one-size-fits-all solution would be overly restrictive. - -The `NttManager` contract allows an M of N threshold for transceiver attestations to determine whether a message can be safely executed. For example, if the threshold requirement is 1, the message will be executed after a single transceiver delivers a valid attestation. If the threshold requirement is 2, the message will only be executed after two transceivers deliver valid attestations. When a transceiver attests to a message, the contract emits the `MessageAttestedTo` event. - -NTT implements replay protection, so if a given transceiver attempts to deliver a message attestation twice, the contract reverts with `TransceiverAlreadyAttestedToMessage` error. NTT also implements replay protection against re-executing messages. This check also acts as reentrancy protection as well. - -If a message has already been executed, the contract ends execution early and emits the `MessageAlreadyExecuted` event instead of reverting via an error. This mitigates the possibility of race conditions from transceivers attempting to deliver the same message when the threshold is less than the total number of available of transceivers (i.e. threshold < totalTransceivers) and notifies the client (off-chain process) so they don't attempt redundant message delivery. - -**Events** - -```ts -/// @notice Emitted when a relayed message is received. -/// @dev Topic0 -/// 0xf557dbbb087662f52c815f6c7ee350628a37a51eae9608ff840d996b65f87475 -/// @param digest The digest of the message. -/// @param emitterChainId The chain ID of the emitter. -/// @param emitterAddress The address of the emitter. -event ReceivedRelayedMessage(bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress); -``` +Doc-Content: https://wormhole.com/docs/products/reference/chain-ids/ +--- BEGIN CONTENT --- +--- +title: Chain IDs +description: This page documents the Wormhole-specific chain IDs for each chain and contrasts them to the more commonly referenced EVM chain IDs originating in EIP-155. +categories: Reference +--- -```ts -/// @notice Emitted when a message is received. -/// @dev Topic0 -/// 0xf6fc529540981400dc64edf649eb5e2e0eb5812a27f8c81bac2c1d317e71a5f0. -/// @param digest The digest of the message. -/// @param emitterChainId The chain ID of the emitter. -/// @param emitterAddress The address of the emitter. -/// @param sequence The sequence of the message. -event ReceivedMessage( - bytes32 digest, uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence -); -``` +# Chain IDs -```ts -/// @notice Emitted when a message has already been executed to notify client of against retries. -/// @dev Topic0 -/// 0x4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef2. -/// @param sourceNttManager The address of the source nttManager. -/// @param msgHash The keccak-256 hash of the message. -event MessageAlreadyExecuted(bytes32 indexed sourceNttManager, bytes32 indexed msgHash); -``` +The following table documents the chain IDs used by Wormhole and places them alongside the more commonly referenced [EVM Chain IDs](https://chainlist.org/){target=\_blank}. -#### Mint or Unlock +!!! note + Please note, Wormhole chain IDs are different than the more commonly referenced EVM [chain IDs](https://eips.ethereum.org/EIPS/eip-155){target=\_blank}, specified in the Mainnet and Testnet ID columns. -Once a transfer has been successfully verified, the tokens can be minted (if the mode is "burning") or unlocked (if the mode is "locking") to the recipient on the destination chain. Note that the source token decimals are bounded between `0` and `TRIMMED_DECIMALS` as enforced in the wire format. The transfer amount is untrimmed (scaled-up) if the destination chain token decimals exceed `TRIMMED_DECIMALS`. Once the appropriate number of tokens have been minted or unlocked to the recipient, the `TransferRedeemed` event is emitted. + + -**Events** +=== "Mainnet" -```ts -/// @notice Emitted when a transfer has been redeemed -/// (either minted or unlocked on the recipient chain). -/// @dev Topic0 -/// 0x504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a91. -/// @param digest The digest of the message. -event TransferRedeemed(bytes32 indexed digest); -``` + | Ethereum | 2 | 1 | +| Solana | 1 | Mainnet Beta-5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d | +| Algorand | 8 | mainnet-v1.0 | +| Aptos | 22 | 1 | +| Arbitrum | 23 | Arbitrum One-42161 | +| Avalanche | 6 | C-Chain-43114 | +| Base | 30 | Base-8453 | +| Berachain | 39 | | +| Blast | 36 | 81457 | +| BNB Smart Chain | 4 | 56 | +| Celestia | 4004 | celestia | +| Celo | 14 | 42220 | +| Cosmos Hub | 4000 | cosmoshub-4 | +| Dymension | 4007 | dymension_1100-1 | +| Evmos | 4001 | evmos_9001-2 | +| Fantom | 10 | 250 | +| Gnosis | 25 | 100 | +| HyperEVM | 47 | | +| Injective | 19 | injective-1 | +| Ink | 46 | | +| Kaia | 13 | 8217 | +| Kujira | 4002 | kaiyo-1 | +| Linea | 38 | 59144 | +| Mantle | 35 | 5000 | +| Mezo | 50 | | +| Monad | 48 | | +| Moonbeam | 16 | 1284 | +| NEAR | 15 | mainnet | +| Neon | 17 | 245022934 | +| Neutron | 4003 | neutron-1 | +| Noble | 4009 | noble-1 | +| Optimism | 24 | 10 | +| Osmosis | 20 | osmosis-1 | +| Polygon | 5 | 137 | +| Provenance | 4008 | pio-mainnet-1 | +| Pythnet | 26 | | +| Scroll | 34 | 534352 | +| SEDA | 4006 | | +| Sei | 32 | pacific-1 | +| Seievm | 40 | | +| SNAXchain | 43 | 2192 | +| Sonic | 52 | 146 | +| Stargaze | 4005 | stargaze-1 | +| Sui | 21 | 35834a8a | +| Terra 2.0 | 18 | phoenix-1 | +| Unichain | 44 | | +| World Chain | 45 | 480 | +| X Layer | 37 | 196 | -### Solana +=== "Testnet" -#### Transfer + | Ethereum Holesky | 10006 | Holesky-17000 | +| Ethereum Sepolia | 10002 | Sepolia-11155111 | +| Solana | 1 | Devnet-EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG | +| Algorand | 8 | testnet-v1.0 | +| Aptos | 22 | 2 | +| Arbitrum Sepolia | 10003 | Sepolia-421614 | +| Avalanche | 6 | Fuji-43113 | +| Base Sepolia | 10004 | Base Sepolia-84532 | +| Berachain | 39 | 80084 | +| Blast | 36 | 168587773 | +| BNB Smart Chain | 4 | 97 | +| Celestia | 4004 | mocha-4 | +| Celo | 14 | Alfajores-44787 | +| Cosmos Hub | 4000 | theta-testnet-001 | +| Dymension | 4007 | | +| Evmos | 4001 | evmos_9000-4 | +| Fantom | 10 | 4002 | +| Gnosis | 25 | Chiado-10200 | +| HyperEVM | 47 | 998 | +| Injective | 19 | injective-888 | +| Ink | 46 | 763373 | +| Kaia | 13 | Kairos-1001 | +| Kujira | 4002 | harpoon-4 | +| Linea | 38 | 59141 | +| Mantle | 35 | Sepolia-5003 | +| Mezo | 50 | 31611 | +| Monad | 48 | 10143 | +| Moonbeam | 16 | Moonbase-Alphanet-1287 | +| NEAR | 15 | testnet | +| Neon | 17 | 245022940 | +| Neutron | 4003 | pion-1 | +| Noble | 4009 | grand-1 | +| Optimism Sepolia | 10005 | Optimism Sepolia-11155420 | +| Osmosis | 20 | osmo-test-5 | +| Polygon Amoy | 10007 | Amoy-80002 | +| Provenance | 4008 | | +| Pythnet | 26 | | +| Scroll | 34 | Sepolia-534351 | +| SEDA | 4006 | seda-1-testnet | +| Sei | 32 | atlantic-2 | +| Seievm | 40 | | +| SNAXchain | 43 | 13001 | +| Sonic | 52 | 57054 | +| Stargaze | 4005 | | +| Sui | 21 | 4c78adac | +| Terra 2.0 | 18 | pisco-1 | +| Unichain | 44 | Unichain Sepolia-1301 | +| World Chain | 45 | 4801 | +| X Layer | 37 | 195 | + +--- END CONTENT --- -A client calls the `transfer_lock` or `transfer_burn` instruction based on whether the program is in `LOCKING` or `BURNING` mode. The program mode is set during initialization. When transferring, the client must specify the amount of the transfer, the recipient chain, the recipient address on the recipient chain, and the boolean flag `should_queue` to specify whether the transfer should be queued if it hits the outbound rate limit. If `should_queue` is set to false, the transfer reverts instead of queuing if the rate limit were to be hit. +Doc-Content: https://wormhole.com/docs/products/reference/consistency-levels/ +--- BEGIN CONTENT --- +--- +title: Wormhole Finality | Consistency Levels +description: This page documents how long to wait for finality before signing, based on each chain’s consistency (finality) level and consensus mechanism. +categories: Reference +--- -!!! note - Using the wrong transfer instruction, i.e. `transfer_lock` for a program that is in `BURNING` mode, will result in an `InvalidMode` error. +# Wormhole Finality -Depending on the mode and instruction, the following will be produced in the program logs: +The following table documents each chain's `consistencyLevel` values (i.e., finality reached before signing). The consistency level defines how long the Guardians should wait before signing a VAA. The finalization time depends on the specific chain's consensus mechanism. The consistency level is a `u8`, so any single byte may be used. However, a small subset has particular meanings. If the `consistencyLevel` isn't one of those specific values, the `Otherwise` column describes how it's interpreted. -```ts -Program log: Instruction: TransferLock -Program log: Instruction: TransferBurn -``` + + +| Ethereum | 200 | 201 | | finalized | ~ 19min | Details | +| Solana | | 0 | 1 | | ~ 14s | Details | +| Algorand | | | 0 | | ~ 4s | Details | +| Aptos | | | 0 | | ~ 4s | Details | +| Arbitrum | 200 | 201 | | finalized | ~ 18min | Details | +| Avalanche | 200 | | | finalized | ~ 2s | Details | +| Base | 200 | 201 | | finalized | ~ 18min | | +| Berachain | 200 | | | finalized | ~ 4s | | +| Blast | 200 | 201 | | finalized | ~ 18min | | +| BNB Smart Chain | 200 | 201 | | finalized | ~ 48s | Details | +| Celestia | | | 0 | | ~ 5s | | +| Celo | 200 | | | finalized | ~ 10s | | +| Cosmos Hub | | | 0 | | ~ 5s | | +| Dymension | | | 0 | | ~ 5s | | +| Evmos | | | 0 | | ~ 2s | | +| Fantom | 200 | | | finalized | ~ 5s | | +| Injective | | | 0 | | ~ 3s | | +| Ink | | | 0 | | ~ 9min | | +| Kaia | 200 | | | finalized | ~ 1s | | +| Kujira | | | 0 | | ~ 3s | | +| Mantle | 200 | 201 | | finalized | ~ 18min | | +| Mezo | | | 0 | | ~ 8s | | +| Monad | | | 0 | | ~ 2s | | +| Moonbeam | 200 | 201 | | finalized | ~ 24s | Details | +| NEAR | | | 0 | | ~ 2s | Details | +| Neutron | | | 0 | | ~ 5s | | +| Optimism | 200 | 201 | | finalized | ~ 18min | | +| Osmosis | | | 0 | | ~ 6s | | +| Polygon | 200 | | | finalized | ~ 66s | Details | +| Scroll | 200 | | | finalized | ~ 16min | | +| Sei | | | 0 | | ~ 1s | | +| Sonic | | | 0 | | ~ 1s | | +| Stargaze | | | 0 | | ~ 5s | | +| Sui | | | 0 | | ~ 3s | Details | +| Terra 2.0 | | | 0 | | ~ 6s | | +| Unichain | 200 | 201 | | finalized | ~ 18min | | +| World Chain | | | 0 | | ~ 18min | | +| X Layer | 200 | 201 | | finalized | ~ 16min | | + +--- END CONTENT --- -Outbound transfers are always added to an Outbox via the `insert_into_outbox` method. This method checks the transfer against the configured outbound rate limit amount to determine whether the transfer should be rate-limited. An `OutboxItem` is a Solana Account that holds details of the outbound transfer. The transfer can be released from the Outbox immediately if no rate limit is hit. The transfer can be released from the Outbox immediately unless a rate limit is hit, in which case it will only be released after the delay duration associated with the rate limit has expired. +Doc-Content: https://wormhole.com/docs/products/reference/contract-addresses/ +--- BEGIN CONTENT --- +--- +title: Contract Addresses +description: This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. +categories: Reference +--- -#### Rate Limit +# Contract Addresses -During the transfer process, the program checks rate limits via the `consume_or_delay` function. The Solana rate-limiting logic is equivalent to the EVM rate-limiting logic. +## Core Contracts -If the transfer amount fits within the current capacity: + + -- Reduce the current capacity -- Refill the inbound capacity for the destination chain -- Add the transfer to the Outbox with `release_timestamp` set to the current timestamp, so it can be released immediately. +=== "Mainnet" -If the transfer amount doesn't fit within the current capacity: - -- If `shouldQueue = true`, add the transfer to the Outbox with `release_timestamp` set to the current timestamp plus the configured `RATE_LIMIT_DURATION`. -- If `shouldQueue = false`, revert with a `TransferExceedsRateLimit` error + | Ethereum | 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B | +| Solana | worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth | +| Algorand | 842125965 | +| Aptos | 0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625 | +| Arbitrum | 0xa5f208e072434bC67592E4C49C1B991BA79BCA46 | +| Avalanche | 0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c | +| Base | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Berachain | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | +| Blast | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| BNB Smart Chain | 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B | +| Celo | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Fantom | 0x126783A6Cb203a3E35344528B26ca3a0489a1485 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| HyperEVM | 0x7C0faFc4384551f063e05aee704ab943b8B53aB3 | +| Injective | inj17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9l2q74d | +| Ink | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | +| Kaia | 0x0C21603c4f3a6387e241c0091A7EA39E43E90bb7 | +| Mantle | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Moonbeam | 0xC8e2b0cD52Cf01b0Ce87d389Daa3d414d4cE29f3 | +| NEAR | contract.wormhole_crypto.near | +| Neutron | neutron16rerygcpahqcxx5t8vjla46ym8ccn7xz7rtc6ju5ujcd36cmc7zs9zrunh | +| Optimism | 0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722 | +| Polygon | 0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7 | +| Pythnet | H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU | +| Scroll | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sei | sei1gjrrme22cyha4ht2xapn3f08zzw6z3d4uxx6fyy9zd5dyr3yxgzqqncdqn | +| Seievm | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | +| SNAXchain | 0xc1BA3CC4bFE724A08FbbFbF64F8db196738665f4 | +| Sui | 0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c | +| Terra 2.0 | terra12mrnzvhx3rpej6843uge2yyfppfyd3u9c3uq223q8sl48huz9juqffcnhp | +| Unichain | 0xCa1D5a146B03f6303baF59e5AD5615ae0b9d146D | +| World Chain | 0xcbcEe4e081464A15d8Ad5f58BB493954421eB506 | +| X Layer | 0x194B123c5E96B9b2E49763619985790Dc241CAC0 | -#### Send +=== "Testnet" -The caller then needs to request each transceiver to send messages via the `release_outbound` instruction. To execute this instruction, the caller needs to pass the account of the Outbox item to be released. The instruction will then verify that the transceiver is one of the specified senders for the message. Transceivers then send the messages based on the verification backend they are using. + | Ethereum Holesky | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | +| Ethereum Sepolia | 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 | +| Solana | 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 | +| Algorand | 86525623 | +| Aptos | 0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625 | +| Arbitrum Sepolia | 0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35 | +| Avalanche | 0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C | +| Base Sepolia | 0x79A1027a6A159502049F10906D333EC57E95F083 | +| Berachain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| Blast | 0x473e002D7add6fB67a4964F13bFd61280Ca46886 | +| BNB Smart Chain | 0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D | +| Celo | 0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56 | +| Fantom | 0x1BB3B4119b7BA9dfad76B0545fb3F531383c3bB7 | +| Gnosis | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| HyperEVM | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| Injective | inj1xx3aupmgv3ce537c0yce8zzd3sz567syuyedpg | +| Ink | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| Kaia | 0x1830CC6eE66c84D2F177B94D544967c774E624cA | +| Linea | 0x79A1027a6A159502049F10906D333EC57E95F083 | +| Mantle | 0x376428e7f26D5867e69201b275553C45B09EE090 | +| Mezo | 0x268557122Ffd64c85750d630b716471118F323c8 | +| Monad | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| Moonbeam | 0xa5B7D85a8f27dd7907dc8FdC21FA5657D5E2F901 | +| NEAR | wormhole.wormhole.testnet | +| Neon | 0x268557122Ffd64c85750d630b716471118F323c8 | +| Neutron | neutron1enf63k37nnv9cugggpm06mg70emcnxgj9p64v2s8yx7a2yhhzk2q6xesk4 | +| Optimism Sepolia | 0x31377888146f3253211EFEf5c676D41ECe7D58Fe | +| Osmosis | osmo1hggkxr0hpw83f8vuft7ruvmmamsxmwk2hzz6nytdkzyup9krt0dq27sgyx | +| Polygon Amoy | 0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35 | +| Pythnet | EUrRARh92Cdc54xrDn6qzaqjA77NRrCcfbr8kPwoTL4z | +| Scroll | 0x055F47F1250012C6B20c436570a76e52c17Af2D5 | +| Sei | sei1nna9mzp274djrgzhzkac2gvm3j27l402s4xzr08chq57pjsupqnqaj0d5s | +| Seievm | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| SNAXchain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| Sui | 0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790 | +| Terra 2.0 | terra19nv3xr5lrmmr7egvrk2kqgw4kcn43xrtd5g0mpgwwvhetusk4k7s66jyv0 | +| Unichain | 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd | +| World Chain | 0xe5E02cD12B6FcA153b0d7fF4bF55730AE7B3C93A | +| X Layer | 0xA31aa3FDb7aF7Db93d18DDA4e19F811342EDF780 | -For example, the Wormhole transceiver will send by calling `post_message` on the Wormhole program, so that the Wormhole Guardians can observe and verify the message. +=== "Devnet" -!!! note - When `revert_on_delay` is true, the transaction will revert if the release timestamp hasn't been reached. When `revert_on_delay` is false, the transaction succeeds, but the outbound release isn't performed. + | Ethereum | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | +| Solana | Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o | +| Algorand | 1004 | +| Aptos | 0xde0036a9600559e295d5f6802ef6f3f802f510366e0c23912b0655d972166017 | +| BNB Smart Chain | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | +| NEAR | wormhole.test.near | +| Sui | 0x5a5160ca3c2037f4b4051344096ef7a48ebf4400b3f385e57ea90e1628a8bde0 | +| Terra 2.0 | terra14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssrc8au | + -The following will be produced in the program logs: +## Token Bridge -```ts -Program log: Instruction: ReleaseOutbound -``` + + -#### Receive +=== "Mainnet" -Similar to EVM, transceivers vary in how they receive messages since message relaying and verification methods may differ between implementations. + | Ethereum | 0x3ee18B2214AFF97000D974cf647E7C347E8fa585 | +| Solana | wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb | +| Algorand | 842126029 | +| Aptos | 0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f | +| Arbitrum | 0x0b2402144Bb366A632D14B83F244D2e0e21bD39c | +| Avalanche | 0x0e082F06FF657D94310cB8cE8B0D9a04541d8052 | +| Base | 0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627 | +| Berachain | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | +| Blast | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | +| BNB Smart Chain | 0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7 | +| Celo | 0x796Dff6D74F3E27060B71255Fe517BFb23C93eed | +| Fantom | 0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2 | +| Injective | inj1ghd753shjuwexxywmgs4xz7x2q732vcnxxynfn | +| Ink | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | +| Kaia | 0x5b08ac39EAED75c0439FC750d9FE7E1F9dD0193F | +| Mantle | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | +| Moonbeam | 0xb1731c586ca89a23809861c6103f0b96b3f57d92 | +| NEAR | contract.portalbridge.near | +| Optimism | 0x1D68124e65faFC907325e3EDbF8c4d84499DAa8b | +| Polygon | 0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE | +| Scroll | 0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d | +| Sei | sei1smzlm9t79kur392nu9egl8p8je9j92q4gzguewj56a05kyxxra0qy0nuf3 | +| Seievm | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | +| SNAXchain | 0x8B94bfE456B48a6025b92E11Be393BAa86e68410 | +| Sui | 0xc57508ee0d4595e5a8728974a4a93a787d38f339757230d441e895422c07aba9 | +| Terra 2.0 | terra153366q50k7t8nn7gec00hg66crnhkdggpgdtaxltaq6xrutkkz3s992fw9 | +| Unichain | 0x3Ff72741fd67D6AD0668d93B41a09248F4700560 | +| World Chain | 0xc309275443519adca74c9136b02A38eF96E3a1f6 | +| X Layer | 0x5537857664B0f9eFe38C9f320F75fEf23234D904 | -The Wormhole transceiver receives a verified Wormhole message on Solana via the `receive_message` entrypoint instruction. Callers can use the `receive_wormhole_message` Anchor library function to execute this instruction. The instruction verifies the Wormhole Verified Action Approvals (VAAs) and stores it in a `VerifiedTransceiverMessage` account. +=== "Testnet" -The following will be produced in the program logs: + | Ethereum Holesky | 0x76d093BbaE4529a342080546cAFEec4AcbA59EC6 | +| Ethereum Sepolia | 0xDB5492265f6038831E89f495670FF909aDe94bd9 | +| Solana | DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe | +| Algorand | 86525641 | +| Aptos | 0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f | +| Arbitrum Sepolia | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | +| Avalanche | 0x61E44E506Ca5659E6c0bba9b678586fA2d729756 | +| Base Sepolia | 0x86F55A04690fd7815A3D802bD587e83eA888B239 | +| Berachain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | +| Blast | 0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2 | +| BNB Smart Chain | 0x9dcF9D205C9De35334D646BeE44b2D2859712A09 | +| Celo | 0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153 | +| Fantom | 0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8 | +| HyperEVM | 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 | +| Injective | inj1q0e70vhrv063eah90mu97sazhywmeegp7myvnh | +| Ink | 0x376428e7f26D5867e69201b275553C45B09EE090 | +| Kaia | 0xC7A13BE098720840dEa132D860fDfa030884b09A | +| Linea | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | +| Mantle | 0x75Bfa155a9D7A3714b0861c8a8aF0C4633c45b5D | +| Mezo | 0xA31aa3FDb7aF7Db93d18DDA4e19F811342EDF780 | +| Monad | 0xF323dcDe4d33efe83cf455F78F9F6cc656e6B659 | +| Moonbeam | 0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96 | +| NEAR | token.wormhole.testnet | +| Neon | 0xEe3dB83916Ccdc3593b734F7F2d16D630F39F1D0 | +| Optimism Sepolia | 0x99737Ec4B815d816c49A385943baf0380e75c0Ac | +| Polygon Amoy | 0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e | +| Scroll | 0x22427d90B7dA3fA4642F7025A854c7254E4e45BF | +| Sei | sei1jv5xw094mclanxt5emammy875qelf3v62u4tl4lp5nhte3w3s9ts9w9az2 | +| Seievm | 0x23908A62110e21C04F3A4e011d24F901F911744A | +| SNAXchain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | +| Sui | 0x6fb10cdb7aa299e9a4308752dadecb049ff55a892de92992a1edbd7912b3d6da | +| Terra 2.0 | terra1c02vds4uhgtrmcw7ldlg75zumdqxr8hwf7npseuf2h58jzhpgjxsgmwkvk | +| Unichain | 0xa10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a | +| World Chain | 0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2 | +| X Layer | 0xdA91a06299BBF302091B053c6B9EF86Eff0f930D | -```ts -Program log: Instruction: ReceiveMessage -``` +=== "Devnet" -`redeem` checks the inbound rate limit and places the message in an Inbox. Logic works the same as the outbound rate limit mentioned previously. + | Ethereum | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | +| Solana | B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE | +| Algorand | 1006 | +| Aptos | 0x84a5f374d29fc77e370014dce4fd6a55b58ad608de8074b0be5571701724da31 | +| BNB Smart Chain | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | +| NEAR | token.test.near | +| Sui | 0xa6a3da85bbe05da5bfd953708d56f1a3a023e7fb58e5a824a3d4de3791e8f690 | +| Terra 2.0 | terra1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrquka9l6 | + -The following will be produced in the program logs: +## Wormhole Relayer -```ts -Program log: Instruction: Redeem -``` + + -#### Mint or Unlock +=== "Mainnet" -The inbound transfer is released and the tokens are unlocked or minted to the recipient through either `release_inbound_mint` if the mode is `BURNING`, or `release_inbound_unlock` if the mode is `LOCKING`. Similar to transfer, using the wrong transfer instruction (such as `release_inbound_mint` for a program that is in locking mode) will result in `InvalidMode` error. + | Ethereum | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Arbitrum | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Avalanche | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Base | 0x706f82e9bb5b0813501714ab5974216704980e31 | +| Berachain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Blast | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| BNB Smart Chain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Celo | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Fantom | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Ink | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Kaia | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Mantle | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Moonbeam | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Optimism | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Polygon | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Scroll | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Seievm | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| SNAXchain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| Unichain | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | +| World Chain | 0x1520cc9e779c56dab5866bebfb885c86840c33d3 | +| X Layer | 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911 | -!!! note - When `revert_on_delay` is true, the transaction will revert if the release timestamp hasn't been reached. When `revert_on_delay` is false, the transaction succeeds, but the minting/unlocking isn't performed. +=== "Testnet" -Depending on the mode and instruction, the following will be produced in the program logs: + | Ethereum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Arbitrum Sepolia | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Avalanche | 0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB | +| Base Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Berachain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| BNB Smart Chain | 0x80aC94316391752A193C1c47E27D382b507c93F3 | +| Celo | 0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84 | +| Fantom | 0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470 | +| Ink | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Monad | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Moonbeam | 0x0591C25ebd0580E0d4F27A82Fc2e24E7489CB5e0 | +| Optimism Sepolia | 0x93BAD53DDfB6132b0aC8E37f6029163E63372cEE | +| Polygon Amoy | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Seievm | 0x362fca37E45fe1096b42021b543f462D49a5C8df | +| Unichain | 0x362fca37E45fe1096b42021b543f462D49a5C8df | -```ts -Program log: Instruction: ReleaseInboundMint -Program log: Instruction: ReleaseInboundUnlock -``` ---- END CONTENT --- +=== "Devnet" -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/faqs/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement FAQs -description: Frequently asked questions about Wormhole Settlement, including smart contract usage, auction fallback, and message execution. -categories: Settlement, Transfer ---- + | Ethereum | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | +| BNB Smart Chain | 0xcC680D088586c09c3E0E099a676FA4b6e42467b4 | + -# Wormhole Settlement FAQs +## CCTP -## Can I use Wormhole Settlement from a smart contract? If so, how is a message signed and relayed? + + -Yes, Wormhole Settlement can be used from a smart contract. The composing protocol's relayer relays the message. For example, Mayan Shuttle (formerly Swap Layer) has a relayer that redeems the VAA on the destination chain to mint USDC and execute the `callData` contained in the payload. +=== "Mainnet" -## What happens if no solver participates in the auction? - -If an auction does not start within the specified deadline, a standard CCTP transfer will proceed directly from the source chain to the destination chain. This is why parameters like `deadline` exist in the token router interface, ensuring a fallback mechanism in case no solver participates. - -## What guarantees does Wormhole Settlement provide for message execution? - -After the user receives the token upfront, the execution of additional contract calls depends on the relayer of the composing protocol. For example, in Mayan Shuttle, the relayer will attempt the swap multiple times, but its success is subject to the parameters defined in the `callData` (e.g., slippage). - -If the slippage tolerance is set too low, the user may receive USDC on the destination chain instead of the intended swap outcome. However, the four basis points (bps) fee is non-refundable, as the service provided by Liquidity Layer (LL) solvers (ensuring front-finality) is separate from the composing protocol's services, such as swaps or deposits. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement -description: Start building with Wormhole Settlement; integrate with the Liquidity Layer and set up Solvers to enable seamless cross-chain asset transfers. -categories: Settlement, Transfer ---- + | Ethereum | 0xAaDA05BD399372f0b0463744C09113c137636f6a | +| Arbitrum | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x09Fb06A271faFf70A651047395AaEb6265265F13 | +| Base | 0x03faBB06Fa052557143dC28eFCFc63FC12843f1D | +| Optimism | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Polygon | 0x0FF28217dCc90372345954563486528aa865cDd6 | -# Wormhole Settlement +=== "Testnet" -## Get Started + | Ethereum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Arbitrum Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Avalanche | 0x58f4c17449c90665891c42e14d34aae7a26a472e | +| Base Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | +| Optimism Sepolia | 0x2703483B1a5a7c577e8680de9Df8Be03c6f30e3c | -This section provides resources to build with Wormhole Settlement, including integrating the Liquidity Layer into your application and running a Solver for efficient cross-chain asset transfers. +=== "Devnet" -
+ N/A + + -- :octicons-code-16:{ .lg .middle } **Build on the Liquidity Layer** +## Settlement Token Router - --- +=== "Mainnet" - Integrate seamlessly with Wormhole's Liquidity Layer, learn key EVM contract functions for fast and secure cross-chain transfers. +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
- [:custom-arrow: Build on the Liquidity layer](/docs/build/transfers/settlement/liquidity-layer/) +=== "Testnet" -- :octicons-code-16:{ .lg .middle } **Run a Settlement Solver** +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ - --- +## Read-Only Deployments - Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. +=== "Mainnet" - [:custom-arrow: Run a Solver](/docs/build/transfers/settlement/solver/) + | Acala | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Corn | 0xa683c66045ad16abb1bCE5ad46A64d95f9A25785 | +| Gnosis | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| Goat | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Karura | 0xa321448d90d4e5b0A732867c18eA198e75CAC48E | +| LightLink | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Oasis | 0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585 | +| Rootstock | 0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 | +| Sonic | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Telos | 0x352A86168e6988A1aDF9A15Cb00017AAd3B67155 | +| Terra | terra1dq03ugtd40zu9hcgdzrsq6z2z4hwhc9tqk2uy5 | +| XPLA | xpla1jn8qmdda5m6f6fqu9qv46rt7ajhklg40ukpqchkejcvy8x7w26cqxamv3w | -
+!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/liquidity-layer/ +Doc-Content: https://wormhole.com/docs/products/reference/glossary/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Liquidity Layer -description: Learn how to build on the Wormhole Liquidity Layer, the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. -categories: Settlement, Transfer +title: Glossary +description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +categories: Basics --- -# Build on the Wormhole Liquidity Layer - -## Introduction - -The Wormhole Liquidity Layer is the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. It allows these protocols to bundle call data containing arbitrary actions that can be executed atomically alongside each transfer. This feature enables developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. The following section describes the key smart contract components for teams seeking to build atop Wormhole Settlement. - -## EVM Functions - -The EVM Token Router is a simple interface against which to integrate. For an integrator, the contracts have two main entry points: `placeMarketOrder` and `placeFastMarketOrder`. - -See the complete list of [Token Router contract addresses](/docs/build/reference/contract-addresses/#settlement-token-router){target=\_blank} for supported networks. - -### Fast Market Order - -The `placeFastMarketOrder` function allows the caller to elect for a _faster-than-finality_ transfer of USDC (with an arbitrary message payload) to the destination chain by setting the `maxFee` and `deadline` parameters. Using this interface does not guarantee that the caller's transfer will be delivered faster than finality; however, any willing market participants can compete for the specified `maxFee` by participating in an auction on the Solana `MatchingEngine` - -```solidity title="`placeFastMarketOrder` Interface" -function placeFastMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, - uint128 maxFee, - uint32 deadline -) external payable returns (uint64 sequence, uint64 fastSequence); -``` - -??? interface "Parameters `placeFastMarketOrder()`" - - `amountIn` ++"uint128"++ +# Glossary - The amount to transfer. +This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - --- +## Chain ID - `targetChain` ++"uint16"++ +Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. - Target chain ID. +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. - --- +## Consistency Level - `redeemer` ++"bytes32"++ +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. - Redeemer contract address. +## Delivery Provider - --- +A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. - `redeemerMessage` ++"bytes"++ +## Emitter - An arbitrary payload for the redeemer. +The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. - --- +## Finality - `maxFee` ++"uint128"++ +The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. - The maximum fee the user wants to pay to execute a fast transfer. +## Guardian - --- +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. - `deadline` ++"uint32"++ +## Guardian Network - The deadline for the fast transfer auction to start. Note: This timestamp should be for the `MatchingEngine` chain (such as Solana) to avoid any clock drift issues between different blockchains. Integrators can set this value to `0` if they don't want to use a deadline. +Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. -The `placeFastMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. +## Guardian Set -### Market Order +The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. -The `placeMarketOrder` function is a _wait-for-full-finality_ USDC transfer with an arbitrary message payload. The Swap Layer, built on top of the Wormhole Settlement, uses this function if the auction on the matching engine for `placeFastMarketOrder` doesn't start within a specific deadline. +## Heartbeat -```solidity title="`placeMarketOrder` Interface" -function placeMarketOrder( - uint128 amountIn, - uint16 targetChain, - bytes32 redeemer, - bytes calldata redeemerMessage, -) external payable returns (uint64 sequence, uint64 protocolSequence); -``` +Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. -??? interface "Parameters `placeMarketOrder()`" +You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. - `amountIn` ++"uint128"++ +## Observation - The amount to transfer. +An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. - --- +## Relayer - `targetChain` ++"uint16"++ +A relayer is any process that delivers VAAs to a destination. - Target chain ID. +## Sequence - --- +A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. - `redeemer` ++"bytes32"++ +## Spy - Redeemer contract address. +A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. - --- +## VAA - `redeemerMessage` ++"bytes"++ +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. - An arbitrary payload for the redeemer. +## Validator -The `placeMarketOrder` function returns a sequence number for the Wormhole Fill message. This function requires the caller to provide a `msg.value` equal to the amount returned by the `messageFee()` function on the `IWormhole.sol` interface. +A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/build/transfers/settlement/solver/ +Doc-Content: https://wormhole.com/docs/products/reference/supported-networks/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Solver -description: Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. -categories: Settlement, Transfer +title: Supported Networks +description: Learn about the networks each Wormhole product supports, and explore links to documentation, official websites, and block explorers. +categories: Reference --- -# Run a Wormhole Settlement Solver - -## Introduction - -This page provides instructions on how to set up, configure, and run a Solver for Wormhole Settlement using the [example solver](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/update-solver-example/solver){target=\_blank}. - -A Solver is an off-chain agent responsible for: - -- Listening to cross-chain transfer requests sent over Wormhole -- Bidding in auctions (on Solana) to fulfill each request -- Facilitating the actual cross-chain transfer by locking/burning assets on Solana and minting/unlocking them on the destination chain -- Rebalancing once the origin chain transaction finalizes and is redeemed back on Solana - -For information on how the protocol functions and its core features, please visit the [Wormhole Settlement](/docs/learn/transfers/settlement/overview/){target=\_blank} page. +# Supported Networks -## Background +Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -The Solana Matching Engine's permissionless English auction is a central component of Wormhole Settlement protocol architecture. The Matching Engine contract allows any third-party solver to interact with the matching engine to place bids or improve existing ones. The contract includes four key instructions: +## Supported Networks by Product -1. `initialize_auction` - creates a new auction account on-chain and sets basic parameters like the auction's token mint, the amount required, and the bidding period details -2. `bid` - allows a solver to place or update a bid on the active auction -3. `finalize_auction` - following the conclusion of the auction, this instruction completes the fast transfer by sending funds to the recipient on the target chain. This instruction may call the Circle CCTP contract or release an NTT contract in the future, depending on the shuttle asset in question. Failure to execute this message within a predefined grace period may result in a penalty for the winning bidder. -4. `cancel_auction` - cancels an open auction when the auction is no longer valid or was created by mistake. The program returns all locked funds to their respective owners + + +
-These instructions work together to carry out the auction as follows: +### Connect -- The solver transfers the bid amount to the program escrow account, which ensures they have liquidity -- With each successful call of `bid`, the program updates the auction to the new highest bidder, and the prior bid is atomically sent back to the originating solver -- The originating solver can repurpose the returned funds and use them to improve their bid -- Following the auction, the winning solver has to call an instruction on the matching engine to execute the intent +| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Solana | SVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Aptos | Move VM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Berachain | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Osmosis | CosmWasm | :x: | :x: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sui | Sui Move VM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+ + +
-When placing a bid, whether initial or improved, the solver must deposit the required funds plus a security deposit into the matching engine contract. In this permissionless auction, the requirement of this principal amount plus the security deposit ensures a solver's credible commitment to fulfill the transfer. Malicious actors could place hollow bids without this safeguard, undermining the auction's credibility and hindering true price discovery. +### NTT -If the winning solver fails to call the `finalize_auction` instruction, other competing solvers may permissionlessly 'slash' the solver by executing the instruction on their behalf and collecting a portion of the original security deposit as a reward. The remaining portion is routed to the user as compensation for the unanticipated delay. This mechanism properly incentivizes timely execution through solver redundancy and competition. +| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Berachain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Gnosis | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| HyperEVM | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs | +| Ink | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Kaia | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Linea | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Monad | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Neon | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Seievm | EVM | :white_check_mark: | :white_check_mark: | :x: | | +| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+ + +
-## Testnet Example Solver +### Token Bridge -You can clone the Wormhole [`example-liquidity-layer`](https://github.com/wormholelabs-xyz/example-liquidity-layer){target=\_blank} repository to use the included [`solver`](https://github.com/wormholelabs-xyz/example-liquidity-layer/tree/main/solver){target=\_blank} directory as an example solver to fulfill fast orders by interacting with the Matching Engine on Solana. +| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Algorand | AVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Aptos | Move VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Berachain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Blast | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Celo | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Fantom | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| HyperEVM | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs | +| Injective | CosmWasm | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Ink | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Kaia | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Linea | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mantle | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mezo | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Monad | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| NEAR | NEAR VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Neon | EVM | :x: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Scroll | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sei | CosmWasm | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Seievm | EVM | :white_check_mark: | :white_check_mark: | :x: | | +| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sui | Sui Move VM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Terra 2.0 | CosmWasm | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Unichain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| World Chain | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| X Layer | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+ + +
-!!!warning - This example is not optimized for performance, has only been tested on Solana devnet, and is not intended for production use. Any assumptions made in this example may not translate to mainnet. +### CCTP -### Prerequisites +| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+ + +
-In order to build and install dependencies locally in this repo, you will need: +### Settlement -- node v20.18.1 -- npmv - get started by installing `nvm` using this [installation guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating){target=\_blank} +| Ethereum | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Solana | SVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sui | Sui Move VM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Unichain | EVM | :white_check_mark: | :x: | :x: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+ + +
-Navigate into the `solver` directory, then run the command below to set up your environment and install the node dependencies and Matching Engine package: +### MultiGov -```sh -make dependencies -``` - -### Set up Config - -The following is an example of a `config.json` file for Solana devnet. The keys here are required for both the publisher and example solver processes. - -```json title="config.json" -{ - "environment": "Testnet", - "zmqChannels": { - "fastVaa": "tcp://localhost:6001", - "finalizedVaa": "tcp://localhost:6002" - }, - "publisher": { - "log": { - "level": "info" - }, - "vaaSpy": { - "host": "localhost:7073", - "enableObservationCleanup": true, - "observationSeenThresholdMs": 1500000, - "observationCleanupIntervalMs": 500, - "observationsToRemovePerInterval": 5, - "delayedThresholdMs": 60000 - } - }, - "solver": { - "log": { - "level": "info", - "filename": "logs/solver.log" - }, - "connection": { - "rpc": "", - "maxTransactionsPerSecond": 5, - "commitment": "processed", - "addressLookupTable": "YourAddressLookupTab1eHere11111111111111111", - "matchingEngine": "mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS", - "mint": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", - "knownAtaOwners": [ - "Payer11111111111111111111111111111111111111", - "Payer11111111111111111111111111111111111112", - "Payer11111111111111111111111111111111111113" - ] - } - }, - "routerEndpoints": [ - { - "chain": "Sepolia", - "endpoint": "0xE57D917bf955FedE2888AAbD056202a6497F1882", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Avalanche", - "endpoint": "0x8Cd7D7C980cd72eBD16737dC3fa04469dcFcf07A", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "OptimismSepolia", - "endpoint": "0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "ArbitrumSepolia", - "endpoint": "0xe0418C44F06B0b0D7D1706E01706316DBB0B210E", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "BaseSepolia", - "endpoint": "0x824Ea687CD1CC2f2446235D33Ae764CbCd08e18C", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - }, - { - "chain": "Polygon", - "endpoint": "0xa098368AaaDc0FdF3e309cda710D7A5f8BDEeCD9", - "rollbackRisk": 0.0069, - "offerEdge": 0.042 - } - ] -} -``` - -The rollback risks and offer edges configured in the sample config are arbitrary placeholders. You should use historical data and your risk tolerance, to determine appropriate values for your project. - -### Listen to Activity +| Ethereum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Solana | SVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Arbitrum | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Avalanche | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Base | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Berachain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Blast | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| BNB Smart Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Celo | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Fantom | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Gnosis | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| HyperEVM | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs | +| Ink | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Kaia | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Linea | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mantle | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Mezo | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Monad | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Moonbeam | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Neon | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Optimism | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Polygon | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Scroll | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sei | CosmWasm | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Seievm | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | | +| SNAXchain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Sonic | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| Unichain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| World Chain | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +| X Layer | EVM | :white_check_mark: | :white_check_mark: | :white_check_mark: | :material-web:Website:material-file-document:Developer Docs:octicons-package-16:Block Explorer | +
+--- END CONTENT --- -The example solver listens to attested Wormhole messages (VAAs) published on the Wormhole Guardian gossip network. To listen to this gossip network and run the VAA publisher, run the command below. Docker compose is used to listen to the Pyth Beacon and start the [`publishActivity`](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/publishActivity.ts){target=\_blank} process. +Doc-Content: https://wormhole.com/docs/products/reference/testnet-faucets/ +--- BEGIN CONTENT --- +--- +title: Testnet Faucets +description: This page includes resources to quickly find the Testnet tokens you need to deploy and test applications and contracts on Wormhole's supported networks. +categories: Reference +--- -```sh -NETWORK=testnet CONFIG=path/to/config.json make run-publisher -``` +# Testnet Faucets -You should see output resembling: +## Get Started -
- Start logging with info level. - 2025-01-21 16:38:28.145 [publisher] info: Environment: Testnet - 2025-01-21 16:38:36.631 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33635, vaaTime=1737499116 - 2025-01-21 16:38:51.044 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33637, vaaTime=1737499130 - 2025-01-21 16:40:24.890 [publisher] info: Fast VAA. chain=OptimismSepolia, sequence=33639, vaaTime=1737499224 -
+Don't let the need for testnet tokens get in the way of buildling your next great idea with Wormhole. Use this guide to quickly locate the testnet token faucets you need to deploy and test applications and contracts on Wormhole's supported networks. -To set up the Pyth Beacon (which is run using make `run-publisher`), you may need to increase the UDP buffer size for the OS: + + +
-=== "Linux" +### EVM - ```sh - sudo sysctl -w net.core.rmem_max=2097152 - sudo sysctl -w net.core.rmem_default=2097152 - ``` +| Ethereum Holesky | EVM | ETH | Alchemy Faucet | +| Ethereum Sepolia | EVM | ETH | Alchemy Faucet | +| Arbitrum Sepolia | EVM | ETH | List of Faucets | +| Avalanche | EVM | AVAX | Official Avalanche Faucet | +| Base Sepolia | EVM | ETH | List of Faucets | +| Berachain | EVM | BERA | Official Berachain Faucet | +| Blast | EVM | ETH | List of Faucets | +| BNB Smart Chain | EVM | BNB | Official BNB Faucet | +| Celo | EVM | CELO | Official Celo Faucet | +| Fantom | EVM | FTM | Official Fantom Faucet | +| Gnosis | EVM | xDAI | Official Gnosis Faucet | +| HyperEVM | EVM | mock USDC | Official Hyperliquid Faucet | +| Ink | EVM | ETH | Official Ink Faucet | +| Kaia | EVM | KAIA | Official Kaia Faucet | +| Linea | EVM | ETH | List of Faucets | +| Mantle | EVM | MNT | Official Mantle Faucet | +| Monad | EVM | MON | Official Monad Faucet | +| Moonbeam | EVM | DEV | Official Moonbeam Faucet | +| Neon | EVM | NEON | Official Neon Faucet | +| Optimism Sepolia | EVM | ETH | Superchain Faucet | +| Polygon Amoy | EVM | POL | Official Polygon Faucet | +| Scroll | EVM | ETH | List of Faucets | +| Unichain | EVM | ETH | QuickNode Faucet | +| World Chain | EVM | ETH | Alchemy Faucet | +| X Layer | EVM | OKB | X Layer Official Faucet | -=== "MacOS" +### SVM - ```sh - sudo sysctl -w net.inet.udp.recvspace=2097152 - ``` +| Pythnet | SVM | ETH | Superchain Faucet | -### Running the Example Solver +### AVM -Using the same config for your publisher, run the example solver with the command below. +| Algorand | AVM | ALGO | Official Algorand Faucet | -```sh -CONFIG=path/to/config.json make run-solver -``` +### CosmWasm -It is recommended you write log output to a file so errors can be tracked. The example config above specifies an example log filename. +| Celestia | CosmWasm | TIA | Discord Faucet | +| Cosmos Hub | CosmWasm | ATOM | Discord Faucet | +| Evmos | CosmWasm | TEVMOS | Official Evmos Faucet | +| Injective | CosmWasm | INJ | Official Injective Faucet | +| Kujira | CosmWasm | KUJI | Discord Faucet | +| Neutron | CosmWasm | NTRN | List of Faucets | +| Noble | CosmWasm | USDC | Circle Faucet | +| Osmosis | CosmWasm | OSMO | Official Osmosis Faucet | +| SEDA | CosmWasm | SEDA | Official SEDA Faucet | +| Sei | CosmWasm | SEI | Sei Atlantic-2 Faucet | +| Terra 2.0 | CosmWasm | LUNA | Terra Official Faucet | -This process reads the following environment variables: +### Move VM -```sh -SOLANA_PRIVATE_KEY_1= -SOLANA_PRIVATE_KEY_2= -SOLANA_PRIVATE_KEY_3= -SOLANA_PRIVATE_KEY_4= -SOLANA_PRIVATE_KEY_5= -``` +| Aptos | Move VM | APT | Official Aptos Faucet | -At least one of these environment variables must be defined as a keypair encoded in base64 format. These payers must have SOL to send transactions on Solana devnet. If they need funds, they can request them from the [Solana devnet faucet](https://faucet.solana.com/){target=\_blank}. +### NEAR VM -The example solver assumes that these payers own USDC Associated Token Accounts(ATAs), which will be used to fulfill fast transfers. These ATAs must be funded with Solana Devnet USDC. If your ATAs need funds, request some at the [Circle testnet faucet](https://faucet.circle.com/){target=\_blank}. +| NEAR | NEAR VM | NEAR | Official NEAR Faucet | -Wallets and their corresponding ATA will be disabled if there are insufficient funds to pay for transactions or fulfill fast transfers. These constraints can be modified using the `updatePayerMinimumLamports` and `updateTokenMinimumBalance` methods. +### Sui Move VM -An address lookup table is required to execute some transactions. Use the command below to create one. +| Sui | Sui Move VM | SUI | List of Faucets | +
+ +--- END CONTENT --- -```sh -CONFIG=path/to/config.json make create-lut -``` +Doc-Content: https://wormhole.com/docs/products/reference/wormhole-formatted-addresses/ +--- BEGIN CONTENT --- +--- +title: Wormhole Formatted Addresses +description: Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +categories: Reference +--- -`SOLANA_PRIVATE_KEY_1` must be defined for this script to work. +# Wormhole Formatted Addresses -The example solver has the following toggles depending on which orders you want to fulfill: +## Introduction -- `enableCctpOrderPipeline()` -- `enableLocalOrderPipeline()` -- `enablePlaceInitialOffer()` -- `enableImproveOffer()` +Wormhole formatted addresses are 32-byte hex representations of addresses from any supported blockchain. Whether an address originates from EVM, Solana, Cosmos, or another ecosystem, Wormhole standardizes all addresses into this format to ensure cross-chain compatibility. -See the comments in [runExampleSolver](https://github.com/wormholelabs-xyz/example-liquidity-layer/blob/update-solver-example/solver/app/runExampleSolver.ts){target=\_blank} for more information. +This uniform format is essential for smooth interoperability in token transfers and messaging across chains. Wormhole uses formatted addresses throughout the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank}, especially in cross-chain transactions, such as transfer functions that utilize the `bytes32` representation for recipient addresses. -This example solver does NOT do the following: +## Platform-Specific Address Formats -- Discriminate between the CCTP source networks. You must add logic to determine whether you want to constrain fulfilling orders from specific networks. This solver will try to fulfill all orders as long as `enableCctpOrderPipeline()` is called -- Discriminate among fulfillment sizes. No logic determines how small or large fast order transfer sizes should be. This solver will try to fulfill anything as long as your balance can handle it -- Add auctions to auction history. We recommend that after settling a complete auction (one that you have won), you write the auction pubkey to a database and have a separate process to add auction history entries to reclaim rent from these auction accounts. The auction history time delay is two hours after the VAA timestamp. This example does not prescribe any specific database, so add whichever you want ---- END CONTENT --- +Each blockchain ecosystem Wormhole supports has its method for formatting native addresses. To enable cross-chain compatibility, Wormhole converts these native addresses into the standardized 32-byte hex format. -Doc-Content: https://wormhole.com/docs/build/transfers/token-bridge/ ---- BEGIN CONTENT --- ---- -title: Get Started with Token Bridge -description: Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. -categories: Token-Bridge, Transfer ---- +Here’s an overview of the native address formats and how they are normalized to the Wormhole format: -# Token Bridge +| Platform | Native Address Format | Wormhole Formatted Address | +|-----------------|----------------------------------|----------------------------| +| EVM | Hex (e.g., 0x...) | 32-byte Hex | +| Solana | Base58 | 32-byte Hex | +| CosmWasm | Bech32 | 32-byte Hex | +| Algorand | Algorand App ID | 32-byte Hex | +| Sui | Hex | 32-byte Hex | +| Aptos | Hex | 32-byte Hex | +| Near | SHA-256 | 32-byte Hex | -## Introduction +These conversions allow Wormhole to interact seamlessly with various chains using a uniform format for all addresses. -Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. +### Address Format Handling -This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} page in the Learn section. +The Wormhole SDK provides mappings that associate each platform with its native address format. You can find this mapping in the Wormhole SDK file [`platforms.ts`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/base/src/constants/platforms.ts#L93-L102){target=\_blank}: -## Prerequisites +```typescript +const platformAddressFormatEntries = [ + ['Evm', 'hex'], + ['Solana', 'base58'], + ['Cosmwasm', 'bech32'], + ['Algorand', 'algorandAppId'], + ['Sui', 'hex'], + ['Aptos', 'hex'], + ['Near', 'sha256'], +]; +``` -To interact with the Wormhole Token Bridge, you'll need the following: +These entries define how the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/007f61b27c650c1cf0fada2436f79940dfa4f211/core/definitions/src/universalAddress.ts#L23){target=\_blank} class handles different address formats based on the platform. -- [The address of the Token Bridge contract](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers +## Universal Address Methods -## How to Interact with Token Bridge Contracts +The `UniversalAddress` class is essential for working with Wormhole formatted addresses. It converts native blockchain addresses into the standardized 32-byte hex format used across Wormhole operations. -The primary functions of the Token Bridge contracts revolve around: +Key functions: -- **Attesting a token** - registering a new token for cross-chain transfers -- **Transferring tokens** - locking and minting tokens across chains -- **Transferring tokens with a payload** - including additional data with transfers + - **`new UniversalAddress()`** - use the `UniversalAddress` constructor to convert native addresses into the Wormhole format -### Attest a Token + ```typescript + const universalAddress = new UniversalAddress('0x123...', 'hex'); + ``` -Suppose a token has never been transferred to the target chain before transferring it cross-chain. In that case, its metadata must be registered so the Token Bridge can recognize it and create a wrapped version if necessary. + - **`toUniversalAddress()`** - converts a platform-specific address into the Wormhole formatted 32-byte hex address -The attestation process doesn't require you to manually input token details like name, symbol, or decimals. Instead, the Token Bridge contract retrieves these values from the token contract itself when you call the `attestToken()` method. + ```typescript + const ethAddress: NativeAddress<'Evm'> = toNative('Ethereum', '0x0C9...'); + const universalAddress = ethAddress.toUniversalAddress().toString(); + ``` -```solidity -function attestToken( - address tokenAddress, - uint32 nonce -) external payable returns (uint64 sequence); -``` + - **`toNative()`** - converts the Wormhole formatted address back to a native address for a specific blockchain platform -??? interface "Parameters" + ```typescript + const nativeAddress = universalAddress.toNative('Evm'); + ``` - `tokenAddress` ++"address"++ - - The contract address of the token to be attested. + - **`toString()`** - returns the Wormhole formatted address as a hex string, which can be used in various SDK operations - --- + ```typescript + console.log(universalAddress.toString()); + ``` - `nonce` ++"uint32"++ +These methods allow developers to convert between native addresses and the Wormhole format, ensuring cross-chain compatibility. - An arbitrary value provided by the caller to ensure uniqueness. +## Convert Between Native and Wormhole Formatted Addresses -??? interface "Returns" +The Wormhole SDK allows developers to easily convert between native addresses and Wormhole formatted addresses when building cross-chain applications. - `sequence` ++"uint64"++ - - A unique identifier for the attestation transaction. +### Convert a Native Address to a Wormhole Formatted Address -??? interface "Example" +Example conversions for EVM and Solana: - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); +=== "EVM" -uint256 wormholeFee = wormhole.messageFee(); + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; -tokenBridge.attestToken{value: wormholeFee}( - address(tokenImpl), // the token contract to attest - 234 // nonce for the transfer +const ethAddress: NativeAddress<'Evm'> = toNative( + 'Ethereum', + '0x0C99567DC6f8f1864cafb580797b4B56944EEd28' ); +const universalAddress = ethAddress.toUniversalAddress().toString(); +console.log('Universal Address (EVM):', universalAddress); ``` -When `attestToken()` is called, the contract emits a Verifiable Action Approval (VAA) containing the token's metadata, which the Guardians sign and publish. +=== "Solana" -You must ensure the token is ERC-20 compliant. If it does not implement the standard functions, the attestation may fail or produce incomplete metadata. + ```typescript + import { toNative } from '@wormhole-foundation/sdk-core'; -### Transfer Tokens +const solAddress: NativeAddress<'Solana'> = toNative( + 'Solana', + '6zZHv9EiqQYcdg52ueADRY6NbCXa37VKPngEHaokZq5J' +); +const universalAddressSol = solAddress.toUniversalAddress().toString(); +console.log('Universal Address (Solana):', universalAddressSol); + ``` -Once a token is attested, a cross-chain token transfer can be initiated following the lock-and-mint mechanism. On the source chain, tokens are locked (or burned if they're already a wrapped asset), and a VAA is emitted. On the destination chain, that VAA is used to mint or release the corresponding amount of wrapped tokens. +The result is a standardized address format that is ready for cross-chain operations. -Call `transferTokens()` to lock/burn tokens and produce a VAA with transfer details. +### Convert Back to Native Addresses -```solidity -function transferTokens( - address token, - uint256 amount, - uint16 recipientChain, - bytes32 recipient, - uint256 arbiterFee, - uint32 nonce -) external payable returns (uint64 sequence); -``` +Below is how you can convert a Wormhole formatted address back to an EVM or Solana native address: -??? interface "Parameters" +```typescript +const nativeAddressEvm = universalAddress.toNative('Evm'); +console.log('EVM Native Address:', nativeAddressEvm); - `token` ++"address"++ - - The address of the token being transferred. +const nativeAddressSolana = universalAddress.toNative('Solana'); +console.log('Solana Native Address:', nativeAddressSolana); +``` - --- +These conversions ensure that your cross-chain applications can seamlessly handle addresses across different ecosystems. - `amount` ++"uint256"++ - The amount of tokens to be transferred. +## Use Cases for Wormhole Formatted Addresses - --- +### Cross-chain Token Transfers - `recipientChain` ++"uint16"++ - The Wormhole chain ID of the destination chain. +Cross-chain token transfers require addresses to be converted into a standard format. For example, when transferring tokens from Ethereum to Solana, the Ethereum address is converted into a Wormhole formatted address to ensure compatibility. After the transfer, the Wormhole formatted address is converted back into the Solana native format. - --- +### Smart Contract Interactions - `recipient` ++"bytes32"++ - The recipient's address on the destination chain. +In smart contract interactions, especially when building dApps that communicate across multiple chains, Wormhole formatted addresses provide a uniform way to reference addresses. This ensures that addresses from different blockchains can interact seamlessly, whether you're sending messages or making cross-chain contract calls. - --- +### DApp Development - `arbiterFee` ++"uint256"++ - Optional fee to be paid to an arbiter for relaying the transfer. +For cross-chain dApp development, Wormhole formatted addresses simplify handling user wallet addresses across various blockchains. This allows developers to manage addresses consistently, regardless of whether they work with EVM, Solana, or another supported platform. - --- +### Relayers and Infrastructure - `nonce` ++"uint32"++ - A unique identifier for the transaction. +Finally, relayers and infrastructure components, such as Wormhole Guardians, rely on the standardized format to efficiently process and relay cross-chain messages. A uniform address format simplifies operations, ensuring smooth interoperability across multiple blockchains. +--- END CONTENT --- -??? interface "Returns" +Doc-Content: https://wormhole.com/docs/products/settlement/concepts/architecture/ +--- BEGIN CONTENT --- +--- +title: Settlement Protocol Architecture +description: Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. +categories: Settlement, Transfer +--- - `sequence` ++"uint64"++ - - A unique identifier for the transfer transaction. +# Settlement Protocol Architecture -??? interface "Example" +## Introduction - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); +This page describes the high-level mechanics of the underlying native swap protocols in the Wormhole SDK. While built on Wormhole messaging, each protocol uses a novel architecture with unique price discovery, scalability, and latency tradeoffs. These designs enable redundancy to handle highly asymmetric flows and sharp volume changes. These sections will cover the following: -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); +- **Wormhole Liquidity Layer** - a cross-chain transfer protocol that utilizes Solana as the central orchestration layer for cross-chain intents, allowing solvers to deploy liquidity from a single Solana-based hub rather than distributing it across each supported chain +- **Mayan Swift** - a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent +- **Mayan MCTP** - a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains -tokenBridge.transferTokens{value: wormholeFee}( - token, // address of the ERC-20 token to transfer - amount, // amount of tokens to transfer - recipientChain, // Wormhole chain ID of the destination chain - recipient, // recipient address on the destination chain (as bytes32) - arbiterFee, // fee for relayer - nonce // nonce for this transfer -); - ``` +## Wormhole Liquidity Layer -Once a transfer VAA is obtained from the Wormhole Guardian network, the final step is to redeem the tokens on the destination chain. Redemption verifies the VAA's authenticity and releases (or mints) tokens to the specified recipient. To redeem the tokens, call `completeTransfer()`. +Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster-than-finality transfers across the Wormhole ecosystem through a novel, Solana-based hub-and-spoke architecture. The hub-and-spoke model leverages interoperable token standards like Circle's CCTP (and Wormhole's NTT), allowing the solver to natively mint and burn assets between chains for intent fulfillment. This architecture allows solvers to facilitate cross-chain transfers by fronting assets on the destination chain and assuming the finality risk of the originating source chain transaction. -```solidity -function completeTransfer(bytes memory encodedVm) external; -``` +Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. -??? interface "Parameters" +![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/products/settlement/concepts/architecture/architecture-1.webp) - `encodedVm` ++"bytes memory"++ - - The signed VAA containing the transfer details. +The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. -!!!note - - The Token Bridge normalizes token amounts to 8 decimals when passing them between chains. Make sure your application accounts for potential decimal truncation - - The VAA ensures the integrity of the message. Only after the Guardians sign the VAA can it be redeemed on the destination chain +### Solvers and Liquidity Fragmentation -### Transfer Tokens with Payload +Traditional intent-based protocols require solvers to distribute their capital across each supported chain in the network. This liquidity fragmentation leads to capital inefficiency and requires complex rebalancing to manage asymmetric flows between chains. As the number of chains increases, solvers face scalability challenges, which can result in market concentration, reducing competition and potentially impacting price discovery in intent execution. -While a standard token transfer moves tokens between chains, a transfer with a payload allows you to embed arbitrary data in the VAA. This data can be used on the destination chain to execute additional logic—such as automatically depositing tokens into a DeFi protocol, initiating a swap on a DEX, or interacting with a custom smart contract. +Using a hub-and-spoke model, the Wormhole Liquidity Layer solves these challenges by consolidating solver liquidity on a single chain, Solana. This model eliminates the need for complex cross-chain rebalancing and simplifies solvers' infrastructure requirements. Solvers only need to consider the finality risk of the originating source chain transaction and the payload size when bidding on transfers. By concentrating liquidity on Solana, the protocol can handle large transfer volumes with a smaller capital base, enhancing capital efficiency and lowering barriers to entry for solvers. This approach promotes competition, improves overall market efficiency, and ultimately benefits users with better prices while still preserving the speed of transactions. -Call `transferTokensWithPayload()` instead of `transferTokens()` to include a custom payload (arbitrary bytes) with the token transfer. +### Enable Unified Liquidity -```solidity -function transferTokensWithPayload( - address token, - uint256 amount, - uint16 recipientChain, - bytes32 recipient, - uint32 nonce, - bytes memory payload -) external payable returns (uint64 sequence); -``` +The novel hub-and-spoke liquidity architecture relies on interoperable token standards that enable cross-chain token fungibility, such as Circle's Cross-Chain Transfer Protocol (CCTP) and Wormhole's Native Token Transfers (NTT). These protocols allow assets to move seamlessly between chains, making unified liquidity possible. On the liquidity hub (Solana), solvers concentrate their liquidity in NTT or CCTP-supported assets, such as USDC. These assets act as the shuttle between chains but may not necessarily be the user's original or final asset. -??? interface "Parameters" +After the Solana auction concludes, the appropriate instructions are called on the CCTP or NTT contract, initiating the transfer from Solana to the destination chain by burning/locking the asset on Solana and sequentially minting on the destination chain. Solvers rebalance their inventory on Solana using these interoperable token standards as well. Once the originating source chain transaction reaches finality and arrives to Solana, the solver can redeem the NTT or CCTP message, minting the inventory for use once again. - `token` ++"address"++ - - The address of the token being transferred. +By leveraging interoperable token standards like NTT, this model of liquidity facilitation for cross-chain intents can arbitrarily scale to any chain or ecosystem while preserving fully unified liquidity. This removes the need for solver "buy-in" when expanding to new chains. Additionally, regardless of proven traction, new chains can access the same level of liquidity for cross-chain intent fulfillment from the first day of mainnet launch as long-standing ecosystems with clear evidence of adoption. This is often overlooked by solvers, who must aggressively prioritize high-flow chains due to high opportunity costs. The model also supports ecosystems without Centralized Exchange (CEX) enabled withdrawals. - --- +### Protocol Flow: How It Works - `amount` ++"uint256"++ - The amount of tokens to be transferred. +1. **Initiation** - users or protocols initiate a transfer via an interface or directly on-chain. They choose between a standard transfer (waiting for finality on the sending chain) or a fast transfer (triggering the auction process). For fast transfers, users or the protocol specify a maximum fee and an auction start deadline - --- + !!! Note + If an auction doesn't start within the set deadline, a standard transfer will proceed directly from the source to the destination chain. - `recipientChain` ++"uint16"++ - The Wormhole chain ID of the destination chain. +2. **Auction** - solvers monitor the Wormhole network for these fast transfer requests and initiate an auction on Solana by offering to fulfill the transfer at or below the user's maximum fee. To start the auction, the solver must transfer the requested funds plus a small security deposit to the Matching Engine contract +3. **Competition** - once initiated, other solvers can participate by submitting lower bids in a simple English auction, aiming to provide users with the best rate. If a new solver submits a better offer, the previous solver's funds and security deposit are returned, with the latest offer taking precedence atomically. This competition ensures that users receive the best possible transfer rate +4. **Fulfillment** - after the auction concludes, the winning solver must complete the transfer within a predefined grace period to earn their fee and reclaim their security deposit. Failure to do so may result in the security deposit being slashed, with the slashed amount compensating the user for delays. This mechanism incentivizes prompt execution. Upon successful completion, the Fast Transfer hub sends the USDC to the user's destination wallet, and the solver receives their security deposit and transfer fee +5. **Settlement** - once the source chain transaction reaches finality, the winning solver can use the finalized Wormhole message to settle the auction with the matching engine and rebalance. This allows the solver to retrieve the original transfer amount into their wallet - --- +## Mayan Swift - `recipient` ++"bytes32"++ - The recipient's address on the destination chain. +Mayan Swift is a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent. - --- +### On-Chain Competitive Price Discovery Mechanism - `nonce` ++"uint32"++ - A unique identifier for the transaction. +Traditional intent-based protocols essentially function as cross-chain limit orders. If the order is profitable, solvers will compete to fulfill it, leading to MEV-like competition focused on speed. While functional, this methodology presents two clear inefficiencies and drawbacks. - --- +First, they lack a competitive price discovery mechanism as limit order prices are typically determined through centralized off-chain systems. Second, in this MEV-like market structure, only a single solver can win, while the others lose out on transaction fees. This dynamic of deadweight loss results in solvers prioritizing high-margin orders, ultimately resulting in elevated fees for end-users without commensurate benefits. - `payload` ++"bytes memory"++ - Arbitrary data payload attached to the transaction. +Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. -??? interface "Returns" - - `sequence` ++"uint64"++ - - A unique identifier for the transfer transaction. +![Mayan Swift - Intent-centric design](/docs/images/products/settlement/concepts/architecture/architecture-2.webp) -??? interface "Example" +### Protocol Flow: How It Works - ```solidity - IWormhole wormhole = IWormhole(wormholeAddr); -ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); +1. **Initiation** - the user creates an order by signing a transaction that locks one of the primary assets (USDC or ETH) into the Mayan smart contract, specifying the desired outcome. -// Get the fee for publishing a message -uint256 wormholeFee = wormhole.messageFee(); + !!!note + If the input asset is not a primary asset, it is converted into a primary asset within the same transaction before the order is submitted. -tokenBridge.transferTokensWithPayload{value: wormholeFee}( - token, // address of the ERC-20 token to transfer - amount, // amount of tokens to transfer - recipientChain, // Wormhole chain ID of the destination chain - recipient, // recipient address on the destination chain (as bytes32) - nonce, // nonce for this transfer - additionalPayload // additional payload data -); - ``` + Each order includes properties such as destination chain, destination wallet address, output token address, minimum output amount, gas drop amount, deadline, and 32 bytes of random hex to prevent collisions. A Keccak-256 hash is then calculated to identify the order -After initiating a transfer on the source chain, the Wormhole Guardian network observes and signs the resulting message, creating a Verifiable Action Approval (VAA). You'll need to fetch this VAA and then call `completeTransferWithPayload()`. +2. **Auction** - solvers observe on-chain data or subscribe to the Mayan explorer web socket (solvers using the Mayan explorer verify the order's integrity by checking the data against the on-chain hash). Once the new order is verified, an on-chain auction on Solana is initiated by passing the order ID and the bid amount, which cannot be lower than the minimum amount. Other solvers can increase the bid by submitting a higher amount before the auction ends +3. **Fulfillment** - the auction ends three seconds after the initial bid. Once the auction ends, the winning solver can execute an instruction that passes their wallet address on the destination chain. This triggers a Wormhole message containing the order ID and the winner's wallet address. Wormhole Guardians then sign this message, allowing the winning solver to fulfill the order on the destination chain by submitting proof of their win and the promised amount to the Mayan contract before the deadline. The Mayan contract deducts a protocol fee (currently 3 basis points) and a referral fee (if applicable), transferring the remaining amount to the user's destination wallet. It also triggers a Wormhole message as proof of fulfillment +4. **Settlement** - after the Wormhole Guardians sign the fulfillment message, the winning solver can submit this message on the source chain to unlock the user's funds and transfer them to their own wallet. Upon fulfillment, the solver has the option to delay triggering a Wormhole message immediately. Instead, they can batch the proofs and, once the batch reaches a certain threshold, issue a batched proof to unlock all orders simultaneously, saving on gas fees -Only the designated recipient contract can redeem tokens. This ensures that the intended contract securely handles the attached payload. On successful redemption, the tokens are minted (if foreign) or released (if native) to the recipient address on the destination chain. For payload transfers, the designated contract can execute the payload's logic at this time. +## Mayan MCTP -```solidity -function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory); -``` +Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. -??? interface "Parameters" +![Mayan MCTP diagram](/docs/images/products/settlement/concepts/architecture/architecture-3.webp) - `encodedVm` ++"bytes memory"++ +### Protocol Flow: How It Works - The signed VAA containing the transfer details. +1. **Initiation** - the user creates an order by signing a transaction that locks one USDC into the Mayan smart contract, specifying the desired outcome. -??? interface "Returns" + !!!note + If the input asset is not USDC, it is converted into a primary asset within the same transaction before the order is submitted. + + The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash - `bytes memory` +2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} +3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules - The extracted payload data. +The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. -## Source Code References +## Where to Go Next -For a deeper understanding of the Token Bridge implementation and to review the actual source code, please refer to the following links: +- To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial +--- END CONTENT --- -- [Token Bridge contract](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol){target=\_blank} -- [Token Bridge interface](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} +Doc-Content: https://wormhole.com/docs/products/settlement/faqs/ +--- BEGIN CONTENT --- +--- +title: Wormhole Settlement FAQs +description: Frequently asked questions about Wormhole Settlement, including smart contract usage, auction fallback, and message execution. +categories: Settlement, Transfer +--- -## Portal Bridge +# Wormhole Settlement FAQs -A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. +## Can I use Wormhole Settlement from a smart contract? If so, how is a message signed and relayed? -## FAQs +Yes, Wormhole Settlement can be used from a smart contract. The composing protocol's relayer relays the message. For example, Mayan Shuttle (formerly Swap Layer) has a relayer that redeems the VAA on the destination chain to mint USDC and execute the `callData` contained in the payload. -### Can ownership of wrapped tokens be transferred from the Token Bridge? +## What happens if no solver participates in the auction? -No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. +If an auction does not start within the specified deadline, a standard CCTP transfer will proceed directly from the source chain to the destination chain. This is why parameters like `deadline` exist in the token router interface, ensuring a fallback mechanism in case no solver participates. - - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself - - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge +## What guarantees does Wormhole Settlement provide for message execution? -The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. +After the user receives the token upfront, the execution of additional contract calls depends on the relayer of the composing protocol. For example, in Mayan Shuttle, the relayer will attempt the swap multiple times, but its success is subject to the parameters defined in the `callData` (e.g., slippage). -Relevant contracts: +If the slippage tolerance is set too low, the user may receive USDC on the destination chain instead of the intended swap outcome. However, the four basis points (bps) fee is non-refundable, as the service provided by Liquidity Layer (LL) solvers (ensuring front-finality) is separate from the composing protocol's services, such as swaps or deposits. +--- END CONTENT --- - - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} - - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} - - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} +Doc-Content: https://wormhole.com/docs/products/settlement/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started +description: Perform a cross-chain token swap using Wormhole Settlement and the Mayan Swift route with the TypeScript SDK on mainnet. +categories: Settlement, Transfer +--- -### How do I update the metadata of a wrapped token? +# Get Started -Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. +[Settlement](/docs/products/settlement/overview/){target=\_blank} is Wormhole’s intent-based execution layer, enabling fast, multichain token transfers. It coordinates routing logic, relayers, and on-chain infrastructure to let users express what they want to be done, not how. -### How do I calculate the current gas costs for Ethereum Mainnet VAA verification? +This guide walks you through performing a real token swap using the [Mayan Swift route](https://mayan.finance){target=_blank}, one of the three integrated Settlement protocols, with the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=_blank}. -You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. +By the end, you'll have a working script that: -### How can I update my wrapped token image on Solscan? +- Resolves token transfer routes using Mayan Swift +- Quotes and validates the best route +- Initiates a swap on a source chain and completes the transfer on a destination chain -Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. +!!! note + Mayan Swift currently supports **mainnet only**. Attempting to run this demo on a testnet will fail. -To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. ---- END CONTENT --- +## Prerequisites -Doc-Content: https://wormhole.com/docs/learn/glossary/ ---- BEGIN CONTENT --- ---- -title: Glossary -description: Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -categories: Basics ---- +Before you begin, ensure you have the following: -# Glossary - -This glossary is an index of technical term definitions for words commonly used in Wormhole documentation. - -## Chain ID +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#settlement){target=\_blank} -Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. +This example uses Ethereum as the source chain and Solana as the destination. As a result, you'll need an Ethereum wallet with ETH for gas and a Solana wallet with SOL for fees. You can adapt the example to match your preferred chains. -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +## Set Up a Project -## Consistency Level +Start by scaffolding a basic Node.js project and installing the required SDKs. -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +1. Create a new project folder: -## Delivery Provider + ```bash + mkdir settlement-swap + cd settlement-swap + npm init -y + ``` -A Delivery Provider monitors for Wormhole Relayer delivery requests and delivers those requests to the intended target chain as instructed. +2. Install the required dependencies: -## Emitter + ```bash + npm install @wormhole-foundation/sdk-connect \ + @wormhole-foundation/sdk-evm \ + @wormhole-foundation/sdk-solana \ + @mayanfinance/wormhole-sdk-route \ + dotenv + npm install -D typescript tsx + ``` -The emitter contract makes the call to the Wormhole Core Contract. The published message includes the emitter contract address and, a sequence number for the message is tracked to provide a unique ID. +3. Create the file structure: -## Finality + ```bash + mkdir src + touch src/helpers.ts src/swap.ts .env .gitignore + ``` -The finality of a transaction depends on its blockchain properties. Once a transaction is considered final, you can assume the resulting state changes it caused won't be reverted. +4. Set up secure access to your wallets. This guide assumes you are loading your `MAINNET_ETH_PRIVATE_KEY` and `MAINNET_SOL_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [cast wallet](https://book.getfoundry.sh/reference/cast/cast-wallet/){target=_blank}. -## Guardian + !!! warning + If you use a .env file during development, add it to your .gitignore to exclude it from version control. Never commit private keys or mnemonics to your repository. -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +## Perform a Token Swap -## Guardian Network +This section shows you how to perform a token swap using the Mayan Swift route. You will define a helper function to configure the source and destination chain signers. -Validators in their own P2P network who serve as Wormhole's oracle by observing activity on-chain and generating signed messages attesting to that activity. +Then, you'll create a script that initiates a transfer on Ethereum, uses the Mayan Swift resolver to find valid routes, sends the transaction, and completes the transfer on Solana. -## Guardian Set +1. Open `helper.ts` and define the `getSigner` utility function to load private keys, instantiate signers for Ethereum and Solana, and return the signers along with the Wormhole-formatted address: -The Guardian Set is a set of guardians responsible for validating a message emitted from the core contracts. Occasionally, the members of the set will change through a governance action. + ```ts title="src/helpers.ts" + import { + Chain, + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, +} from '@wormhole-foundation/sdk-connect'; +import { getEvmSignerForKey } from '@wormhole-foundation/sdk-evm'; +import { getSolanaSigner } from '@wormhole-foundation/sdk-solana'; -## Heartbeat +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (MAINNET_ETH_PRIVATE_KEY, MAINNET_SOL_PRIVATE_KEY) + * must be loaded securely beforehand, for example via a keystore, + * secrets manager, or environment variables (not recommended). + */ +// Define Transfer Interface +export interface SignerContext { + signer: Signer; + address: ChainAddress; +} -Each Guardian will issue a `heartbeat` on a 15-second interval to signal that it is still running and convey details about its identity, uptime, version, and the status of the connected nodes. +export async function getSigner( + chain: ChainContext +): Promise> { + let signer: Signer; + const platform = chain.platform.utils()._platform; + switch (platform) { + case 'Solana': + signer = await getSolanaSigner( + await chain.getRpc(), + getEnv('MAINNET_SOL_PRIVATE_KEY') + ); + break; + case 'Evm': + signer = await getEvmSignerForKey( + await chain.getRpc(), + getEnv('MAINNET_ETH_PRIVATE_KEY') + ); + break; + default: + throw new Error('Unrecognized platform: ' + platform); + } -You can view the heartbeats on the [Wormhole dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. + return { + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} + + ``` -## Observation +2. In `swap.ts`, add the following script, which will handle all of the logic required to perform the token swap: -An Observation is a data structure describing a message emitted by the Core Contract and noticed by the Guardian node. + ```ts title="src/swap.ts" + import { Wormhole, routes } from '@wormhole-foundation/sdk-connect'; +import { EvmPlatform } from '@wormhole-foundation/sdk-evm'; +import { SolanaPlatform } from '@wormhole-foundation/sdk-solana'; +import { MayanRouteSWIFT } from '@mayanfinance/wormhole-sdk-route'; +import { getSigner } from './helpers'; -## Relayer +(async function () { + // Setup + const wh = new Wormhole('Mainnet', [EvmPlatform, SolanaPlatform]); -A relayer is any process that delivers VAAs to a destination. + const sendChain = wh.getChain('Ethereum'); + const destChain = wh.getChain('Solana'); -## Sequence + // To transfer native ETH on Ethereum to native SOL on Solana + const source = Wormhole.tokenId(sendChain.chain, 'native'); + const destination = Wormhole.tokenId(destChain.chain, 'native'); -A nonce, strictly increasing, which is tracked by the Wormhole Core Contract and unique to the emitter chain and address. + // Create a new Wormhole route resolver, adding the Mayan route to the default list + // @ts-ignore: Suppressing TypeScript error because the resolver method expects a specific type, + // but MayanRouteSWIFT is compatible and works as intended in this context. + const resolver = wh.resolver([MayanRouteSWIFT]); -## Spy + // Show supported tokens + const dstTokens = await resolver.supportedDestinationTokens( + source, + sendChain, + destChain + ); + console.log(dstTokens.slice(0, 5)); -A Spy is a daemon that eavesdrops on the messages passed between Guardians, typically to track VAAs as they get signed. + // Load signers and addresses from helpers + const sender = await getSigner(sendChain); + const receiver = await getSigner(destChain); -## VAA + // Creating a transfer request fetches token details + // since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source, + destination, + }); -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + const bestRoute = foundRoutes[0]!; -## Validator + // Specify the amount as a decimal string + const transferParams = { + amount: '0.002', + options: bestRoute.getDefaultOptions(), + }; -A daemon configured to monitor a blockchain node and observe messages emitted by the Wormhole contracts. ---- END CONTENT --- + // Validate the queries route + let validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) { + console.error(validated.error); + return; + } + console.log('Validated: ', validated); -Doc-Content: https://wormhole.com/docs/learn/governance/architecture/ ---- BEGIN CONTENT --- ---- -title: MultiGov Architecture -description: Discover MultiGov's hub-and-spoke architecture, enabling secure cross-chain governance with Wormhole’s interoperability and decentralized coordination. -categories: MultiGov ---- + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) { + console.error(`Error fetching a quote: ${quote.error.message}`); + return; + } + console.log('Quote: ', quote); + + // Initiate the transfer + const receipt = await bestRoute.initiate( + tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); -# MultiGov Architecture + await routes.checkAndCompleteTransfer( + bestRoute, + receipt, + receiver.signer, + 15 * 60 * 1000 + ); +})(); + ``` -MultiGov employs a hub-and-spoke model to enable cross-chain governance, utilizing Wormhole's interoperability infrastructure for secure cross-chain communication. This architecture allows coordinated decision-making across multiple blockchain networks while maintaining a central coordination point. +3. Execute the script to initiate and complete the transfer: -## Key Components + ```bash + npx tsx src/swap.ts + ``` -### Hub Chain Contracts + If successful, you’ll see terminal output like this: -The hub chain is the central point for managing proposals, tallying votes, executing decisions, and coordinating governance across connected chains. +
+npx tsx src/swap.ts +Validated: { valid: true, ... } +Quote: { success: true, ... } +Initiated transfer with receipt: ... +Checking transfer state... +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: SourceInitiated +Current Transfer State: DestinationFinalized + +
- - **`HubGovernor`** - central governance contract managing proposals and vote tallying - - **`HubVotePool`** - receives aggregated votes from spokes and submits them to `HubGovernor` - - **`HubMessageDispatcher`** - relays approved proposal executions to spoke chains - - **`HubProposalExtender`** - allows trusted actors to extend voting periods if needed - - **`HubProposalMetadata`** - helper contract returning `proposalId` and vote start for `HubGovernor` proposals - - **`HubEvmSpokeAggregateProposer`** - aggregates cross-chain voting weight for an address and proposes via the `HubGovernor` if eligible +Congratulations! You've just completed a cross-chain token swap from Ethereum to Solana using Settlement. -### Spoke Chains Contracts +## Customize the Integration -Spoke chains handle local voting, forward votes to the hub, and execute approved proposals from the hub for decentralized governance. +You can tailor the example to your use case by adjusting: - - **`SpokeVoteAggregator`** - collects votes on the spoke chain and forwards them to the hub - - **`SpokeMessageExecutor`** - receives and executes approved proposals from the hub - - **`SpokeMetadataCollector`** - fetches proposal metadata from the hub for spoke chain voters - - **`SpokeAirlock`** - acts as governance's "admin" on the spoke, has permissions, and its treasury +- **Tokens and chains**: Use `getSupportedTokens()` to explore what's available. +- **Source and destination chains**: Modify `sendChain` and `destChain` in `swap.ts`. +- **Transfer settings**: Update the amount or route parameters. +- **Signer management**: Modify `src/helpers.ts` to integrate with your preferred wallet setup. -### Spoke Solana Staking Program +## Next Steps -The Spoke Solana Staking Program handles local voting from users who have staked W tokens or are vested in the program, forwards votes to the hub, and executes approved proposals from the hub for decentralized governance. +Once you've chosen a path, follow the corresponding guide to start building: -The program implements its functionality through instructions, using specialized PDA accounts where data is stored. Below are the key accounts in the program: +- [**`demo-mayanswift`**](https://github.com/wormhole-foundation/demo-mayanswift){target=_blank}: Check out the repository for the full code example. + +--- END CONTENT --- - - **`GlobalConfig`** - global program configuration - - **`StakeAccountMetadata`** - stores user's staking information - - **`CustodyAuthority`** - PDA account managing custody and overseeing token operations related to stake accounts - - **`StakeAccountCustody`** - token account associated with a stake account for securely storing staked tokens - - **`CheckpointData`** - tracks delegation history - - **`SpokeMetadataCollector`** - collects and updates proposal metadata from the hub chain - - **`GuardianSignatures`** - stores guardian signatures for message verification - - **`ProposalData`** - stores data about a specific proposal, including votes and start time - - **`ProposalVotersWeightCast`** - tracks individual voter's weight for a proposal - - **`SpokeMessageExecutor`** - processes messages from a spoke chain via the Wormhole protocol - - **`SpokeAirlock`** - manages PDA signing and seed validation for secure instruction execution - - **`VestingBalance`** - stores total vesting balance and related staking information of a vester - - **`VestingConfig`** - defines vesting configuration, including mint and admin details - - **`Vesting`** - represents individual vesting allocations with maturation data - - **`VoteWeightWindowLengths`** - tracks lengths of vote weight windows +Doc-Content: https://wormhole.com/docs/products/settlement/overview/ +--- BEGIN CONTENT --- +--- +title: Settlement Overview +description: Discover how Settlement enables fast, intent-based token transfers across chains using a unified system of solver auctions and integrated execution routes. +categories: Settlement, Transfer +--- -Each account is implemented as a Solana PDA (Program Derived Address) and utilizes Anchor's account framework for serialization and management. +# Settlement Overview -## System Workflow +Wormhole Settlement is a multichain transfer system that allows users to specify what they want to happen, such as sending or swapping tokens, without handling the execution themselves. Instead, off-chain agents called solvers compete to fulfill these user intents. -The MultiGov system workflow details the step-by-step process for creating, voting on, and executing governance proposals across connected chains, from proposal creation to final cross-chain execution. +Settlement prioritizes speed, execution quality, and reliability. Its primary route, Mayan Swift, leverages fast off-chain auctions among a curated set of solvers to achieve low-latency bridging with minimal slippage. All settlement steps remain verifiable on-chain through Wormhole messages. -### EVM Governance Workflow +For broader use cases and protocol-level execution, Mayan MCTP provides an alternative path. It wraps Circle’s CCTP to facilitate native USDC bridging and token delivery in a single, verifiable flow. While slower due to chain finality constraints, MCTP offers a reliable mechanism for cross-chain transfers. -The EVM-based MultiGov workflow follows these steps: +## Key Features -1. **Proposal creation**: - 1. A user creates a proposal through the `HubEvmSpokeAggregateProposer`, which checks eligibility across chains, or directly on the `HubGovernor` via the `propose` method - 2. The proposal is submitted to the `HubGovernor` if the user meets the proposal threshold -2. **Proposal metadata distribution**: - 1. `HubProposalMetadata` creates a custom view method to be queried for use in the `SpokeMetadataCollector` - 2. `SpokeMetadataCollector` on each spoke chain queries `HubProposalMetadata` for proposal details -3. **Voting process**: - 1. Users on spoke chains vote through their respective `SpokeVoteAggregators` - 2. `SpokeVoteAggregators` send aggregated votes to the `HubVotePool` via Wormhole - 3. `HubVotePool` submits the aggregated votes to the `HubGovernor` -4. **Vote tallying and proposal execution**: - 1. `HubGovernor` tallies votes from all chains - 2. If a quorum is reached and there are more for votes than against votes, the vote passes and is queued for execution - 3. After the timelock delay, the proposal can be executed on the hub chain - 4. For cross-chain actions, a proposal should call the `dispatch` method in the `HubMessageDispatcher`, which sends execution messages to the relevant spoke chains - 5. `SpokeMessageExecutors` on each spoke chain receive and execute the approved actions through their respective `SpokeAirlocks` +- **Intent-based architecture**: Users express what they want to happen (e.g., swap X for Y on chain Z), and solvers execute it. +- **Solver auctions**: Solvers compete in on-chain auctions for the right to fulfill intents, improving execution quality. +- **Fast and fallback-capable**: Combines high-speed execution with a reliable fallback path. +- **Minimal slippage**: Settlement abstracts away complex balancing operations and uses shuttle assets like USDC and tokens deployed via NTT. +- **On-chain verifiability**: Even though auctions are off-chain, all settlement steps remain verifiable on-chain via Wormhole messages. +- **Two integrated routes**: Mayan Swift for speed, Mayan MCTP for compatibility and redundancy. -### Solana Governance Workflow +## How It Works -The Solana-based MultiGov workflow follows these steps: +At the core of Settlement are two components: -1. **Proposal creation**: - 1. A user creates a proposal on `HubGovernor` by calling the `propose` method, provided they meet the proposal threshold - 2. For the proposal to be executed on the Solana blockchain, a `SolanaPayload` must be generated and included in the `calldata` parameter of the `propose` function - 3. The `SolanaPayload` contains encoded details specifying which instructions will be executed and which Solana program is responsible for execution +- **Intents**: Signed transactions where a user defines what outcome they want (e.g., send USDC to another chain and receive ETH). It abstracts what the user wants, not how it should be executed. +- **Solvers**: Third-party agents that compete in auctions to fulfill these intents. They front capital, perform swaps or transfers, and receive fees in return. -2. **Proposal metadata distribution**: - 1. A user queries `getProposalMetadata` from `HubProposalMetadata` via the Wormhole query system to create a proposal on the **Spoke Solana Chain Staking Program** - 2. The retrieved metadata is used in the `AddProposal` instruction in the Solana program - 3. The proposal data is verified to ensure it matches the expected format - 4. Guardian signatures are posted using the `PostSignatures` instruction - 5. Once validated, the proposal is stored on-chain +Settlement currently supports the following integrated protocols. -3. **Voting process**: - 1. Users vote on proposals stored in the `ProposalData` account on Solana - 2. The `CastVote` instruction records their choice (`for_votes`, `against_votes`, or `abstain_votes`) - 3. Eligibility and vote weight are verified using historical voter checkpoint data - 4. A **Query Wormhole** request retrieves vote data from a Solana PDA - 5. The signed response from Wormhole guardians is submitted to the `HubVotePool` on Ethereum for verification - 6. The `crossChainVote` function in `HubVotePool` processes the validated response and forwards the aggregated vote data to the `HubGovernor` to finalize the decision +### Mayan Swift -4. **Vote tallying and proposal execution**: - 1. `HubGovernor` tallies votes from all chains - 2. If a quorum is reached with more **for votes** than **against votes**, the proposal passes and is queued for execution - 3. After the timelock delay, the proposal can be executed either on the hub chain or another chain - 4. For cross-chain execution involving Solana, the proposal calls the `dispatch` method in `HubSolanaMessageDispatcher`, which sends execution messages to Solana - 5. On Solana, the `ReceiveMessage` instruction processes the approved message, and the `SpokeAirlock` executes the corresponding instructions +Mayan Swift implements a traditional intent-based architecture, where solvers compete to fulfill user intents by utilizing their inventory. It offers fast execution, typically around 12 seconds. To participate, solvers must hold assets on multiple chains, which can lead to imbalances: some chains may get depleted while others accumulate excess. This requires occasional rebalancing and adds operational overhead. Despite that, Mayan Swift is ideal for high-speed transfers and benefits from open, competitive auctions that can drive down execution prices. -## Cross-Chain Communication +The diagram below shows how Mayan Swift handles a cross-chain intent when a user wants to swap ARB on Arbitrum for WIF on Solana. Behind the scenes, the process is more involved and relies on solver-managed liquidity across both chains. -MultiGov relies on Wormhole's infrastructure for all cross-chain messaging, ensuring secure and reliable communication between chains. Wormhole's cross-chain state read system, known as Queries, is used for vote aggregation and proposal metadata. Additionally, cross-chain proposal execution messages are transmitted through Wormhole's custom relaying system, enabling seamless coordination across multiple blockchain networks. +1. **Solver initiates on Arbitrum**: Solver swaps ARB → ETH and deposits ETH into an escrow on Arbitrum. +2. **VAA emitted to Solana**: A [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} triggers the solver to release SOL on Solana, which is swapped to WIF using an aggregator. +3. **User receives WIF**: Once the user receives WIF, a second VAA is emitted to finalize the transfer and releases the ETH held in the escrow to the solver. +4. **Failure handling**: If any step fails, the ETH in escrow is either retained or returned to the user — the solver only gets paid if execution succeeds. -## Security Measures +```mermaid +sequenceDiagram + participant User + participant Solver_ARB as Solver (Arbitrum) + participant Escrow + participant Wormhole + participant Solver_SOL as Solver (Solana) + participant Aggregator -- **Vote weight window** - implements a moving window for vote weight checkpoints to mitigate cross-chain double voting - - **Proposal extension** - `HubProposalExtender` allows for extending voting periods by a trusted actor in the case of network issues or high-stakes decisions -- **Timelock** - a timelock period between proposal approval and execution allows for additional security checks and community review -- **Wormhole verification** - all cross-chain messages are verified using Wormhole's secure messaging protocol + Note over User,Aggregator: User has ARB and wants WIF -## Detailed Architecture Diagram + User->>Solver_ARB: Submit intent (ARB → WIF) + Solver_ARB->>Escrow: Swaps ARB → ETH and deposits ETH + Escrow-->>Wormhole: Emits VAA + Wormhole-->>Solver_SOL: Delivers VAA + Solver_SOL->>Aggregator: Releases SOL and swaps to WIF + Aggregator->>Solver_SOL: Receives WIF + Solver_SOL->>User: Sends WIF + User-->>Wormhole: Emits final VAA + Wormhole-->>Escrow: Confirms receipt + Escrow->>Solver_ARB: Releases ETH to solver +``` -This architecture ensures that MultiGov can operate securely and efficiently across multiple chains, allowing for truly decentralized and cross-chain governance while maintaining a unified decision-making process. +### Mayan MCTP - -![detailed multigov architecture diagram](/docs/images/learn/governance/multigov-detailed.webp) ---- END CONTENT --- +Mayan MCTP is a fallback protocol that wraps Circle’s CCTP into the Settlement framework. It bundles USDC bridging and swaps into a single operation handled by protocol logic. This route is slower due to its reliance on chain finality. However, it provides broad compatibility and redundancy, making it useful when faster routes are unavailable or when targeting chains that aren’t supported by Swift. While typically more expensive due to protocol fees, it ensures reliable settlement when faster options are unavailable. -Doc-Content: https://wormhole.com/docs/learn/governance/faq/ ---- BEGIN CONTENT --- ---- -title: MultiGov Theoretical FAQs -description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. -categories: MultiGov ---- +## Use Cases -# FAQs +- **Cross-Chain Perpetuals** -## General Questions + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Provides fast token execution across chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch live prices and manage position state across chains. -### What is MultiGov? +- **Bridging Intent Library** -MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. It leverages Wormhole's interoperability infrastructure for seamless voting and proposal mechanisms across various chains. + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Handles user-defined bridge intents. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Triggers cross-chain function calls. -### How does MultiGov differ from traditional DAO governance? +- **Multichain Prediction Markets** -Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Executes token flows between chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Gets market data and tracks state. -### What are the main components of MultiGov? +## Next Steps -The main components of MultiGov include: +Start building with Settlement or dive deeper into specific components: -- **Hub chain** - central coordination point for governance activities -- **Spoke chains** - additional chains where token holders can participate in governance -- **Wormhole integration** - enables secure cross-chain message passing -- **Governance token** - allows holders to participate in governance across all integrated chains +- **[Get Started with Settlement](/docs/products/settlement/get-started/)**: Follow a hands-on demo using Mayan Swift. +- **[Architecture Documentation](/docs/products/settlement/concepts/architecture/)**: Explore the Settlement architecture and components. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/governance/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/concepts/payload-structure/ --- BEGIN CONTENT --- --- -title: Learn about MultiGov -description: Explore the MultiGov documentation for a comprehensive guide covering architecture, deployment, upgrading, integration, and FAQs. -categories: MultiGov +title: Token Bridge Payload Structure +description: Discover the structure and purpose of each Token Bridge payload, including Transfer, TransferWithPayload, AssetMeta, and governance messages. +categories: Token-Bridge, Transfers --- -# MultiGov +# Message and Payload Structure -Discover everything you need to know about MultiGov, Wormhole's cross-chain governance solution. Get an introduction to the core concepts, explore how the system's components work together, and find answers to common questions to help you navigate the platform effectively. +To enable secure and flexible cross-chain token transfers, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} defines a set of standardized payloads. These payloads are embedded in [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} and processed by bridge contracts on the source and destination chains. Each payload has a unique format and serves a specific role in the lifecycle of token bridging. -## Get Started +This page outlines each payload type in detail. -
+## Transfer -- :octicons-book-16:{ .lg .middle } **Overview** +The `Transfer` payload (ID = `1`) is the core mechanism for moving tokens across chains. It is emitted when a user locks or burns tokens on the source chain. On the destination chain, it instructs the bridge to either mint a wrapped token or release native tokens from custody. - --- +```text +PayloadID uint8 = 1 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +Fee uint256 +``` - Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. +??? interface "Parameters" - [:custom-arrow: Take a first glance at MultiGov](/docs/learn/governance/overview/) + `PayloadID` ++"uint8"++ -- :octicons-book-16:{ .lg .middle } **Architecture** + Value must be `1`, indicating a `Transfer` operation. --- - Discover MultiGov's hub-and-spoke architecture, enabling EVM and Solana cross-chain governance through coordinated decision-making. - - [:custom-arrow: Learn about MultiGov architecture](/docs/learn/governance/architecture/) + `Amount` ++"uint256"++ -- :octicons-question-16:{ .lg .middle } **Theoretical FAQs** + Amount being transferred, truncated to 8 decimals for consistency across all chains. --- - Find answers to common theoretical questions about MultiGov. + `TokenAddress` ++"bytes32"++ - [:custom-arrow: Find the answer to your theoretical questions](/docs/learn/governance/faq/) - -
+ Address of the token. Left-zero-padded if shorter than 32 bytes + + --- -## Next Steps + `TokenChain` ++"uint16"++ -
+ Chain ID of the token. + + --- -- :octicons-checklist-16:{ .lg .middle } **Begin the MultiGov Integration Process** + `To` ++"bytes32"++ + Address of the recipient. Left-zero-padded if shorter than 32 bytes. + --- - Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. + `ToChain` ++"uint16"++ - [:custom-arrow: Start the integration process now](/docs/build/multigov/) + Chain ID of the recipient. + + --- -- :octicons-rocket-16:{ .lg .middle } **Deploy to EVM Chains** + `Fee` ++"uint256"++ - --- + Amount of tokens that the user is willing to pay as relayer fee. Must be less than Amount. Optional and can be claimed by relayers who submit the VAA on the target chain. + - Set up and deploy MultiGov on EVM chains with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. +To keep `Transfer` messages small, they don't carry all the token's metadata. However, this means that before a token can be transferred to a new chain for the first time, the metadata needs to be bridged, and the wrapped asset needs to be created. Metadata, in this case, includes the number of decimals, which is a core requirement for instantiating a token. - [:custom-arrow: Discover how to deploy MultiGov](/docs/build/multigov/deploy-to-evm/) +## AssetMeta -- :octicons-rocket-16:{ .lg .middle } **Deploy to Solana** +Before a token can be transferred to a new chain for the first time, its metadata must be attested using the `AssetMeta` payload (ID = `2`). This ensures proper decimal precision and display. - --- +```text +PayloadID uint8 = 2 +TokenAddress [32]uint8 +TokenChain uint16 +Decimals uint8 +Symbol [32]uint8 +Name [32]uint8 +``` - Set up and deploy the MultiGov Staking Program on Solana with step-by-step instructions for configuring, funding, deploying, and initializing the program. +??? interface "Parameters" - [:custom-arrow: Discover how to deploy MultiGov on Solana](/docs/build/multigov/deploy-to-solana/) + `PayloadID` ++"uint8"++ -- :octicons-code-square-16:{ .lg .middle } **Tutorials** + Value must be `2`, indicating a `AssetMeta` operation. --- - Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. + `TokenAddress` ++"[32]uint8"++ + + Address of the token. Left-zero-padded if shorter than 32 bytes. + + --- - [:custom-arrow: Create MultiGov solutions](/docs/tutorials/multigov/) + `TokenChain` ++"uint16"++ -- :octicons-question-16:{ .lg .middle } **Technical FAQs** + Chain ID of the token. --- - Find answers to common technical questions about MultiGov, covering technical setup, security, proposal creation, and more. + `Decimals` ++"uint8"++ - [:custom-arrow: Find the answer to your technical questions](/docs/build/multigov/faq/) + Number of decimals the token uses on its native chain (not truncated to 8). -
---- END CONTENT --- + --- -Doc-Content: https://wormhole.com/docs/learn/governance/overview/ ---- BEGIN CONTENT --- ---- -title: MultiGov Overview -description: Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. -categories: MultiGov ---- - -# MultiGov: Cross-Chain Governance with Wormhole - -## Overview - -### What Is MultiGov and Why Is It Important? - -MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. By leveraging Wormhole's interoperability infrastructure, MultiGov enables seamless voting and proposal mechanisms across various chains. - -MultiGov is important because it: - -- **Increases participation** by allowing token holders from multiple chains to engage in governance -- **Enhances security** by leveraging Wormhole's robust cross-chain communication -- **Improves scalability** by integrating any chain supported by Wormhole -- **Enables unified governance** and coordinated decision-making across multiple networks - -### Key Features - -- **Hub and spoke model** - central coordination on a hub chain with participation from multiple spoke chains. A hub chain is where the governance state lives, while the spoke chains can be considered extensions of governance that allow for participation by token holders on other chains -- **Cross-chain voting** - token holders on any integrated chain can cast votes -- **Vote aggregation** - votes from all chains are collected and tallied on the hub -- **Cross-chain proposal execution** - approved proposals can be executed across multiple chains -- **Wormhole integration** - secure and reliable cross-chain communication -- **Flexible architecture** - can integrate with any Wormhole-supported blockchain - -### High-Level Architecture Diagram + `Symbol` ++"[32]uint8"++ -The diagram below represents MultiGov's high-level architecture, focusing on its hub-and-spoke model for decentralized governance across multiple chains. The hub chain acts as the central governance controller, managing proposal creation, vote tallying, and execution, while the spoke chains handle local voting and proposal execution on individual chains. The hub and spoke chains communicate via Wormhole's cross-chain messaging infrastructure, ensuring secure and efficient governance across multiple blockchain networks. + Symbol of the token, UTF-8 encoded and padded to 32 bytes. -For a deeper understanding of the system's structure and how the components interact, refer to the [MultiGov Architecture](/docs/learn/governance/architecture/){target=\_blank} page. + --- - -![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/learn/governance/multigov-high-level.webp) ---- END CONTENT --- + `Name` ++"[32]uint8"++ -Doc-Content: https://wormhole.com/docs/learn/ ---- BEGIN CONTENT --- ---- -title: Learn about Wormhole -description: Learn the basics of Wormhole, covering its architecture, messaging protocols, and how it enables multichain communication and asset transfers. -template: root-index-page.html ---- + Name of the token, UTF-8 encoded and padded to 32 bytes. -# Learn +## TransferWithPayload -These informational sections will help you get to know Wormhole. Start with the fundamentals, then discover Wormhole's multichain transfer products and governance system. +The `TransferWithPayload` payload (ID = `3`) extends the standard token transfer by allowing developers to include arbitrary data. This enables interactions with destination chain smart contracts, such as triggering swaps or staking. -## Fundamentals +```text +PayloadID uint8 = 3 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +FromAddress bytes32 +Payload bytes +``` -To understand Wormhole from the ground up, visit the following sections. +??? interface "Parameters" -
+ `PayloadID` ++"uint8"++ -- :octicons-book-16:{ .lg .middle } **Introduction to Wormhole** + Value must be `3`, indicating a `TransferWithPayload` operation. --- - Learn more about the problems Wormhole solves, explore use cases, and view a list of supported blockchains. + `Amount` ++"uint256"++ - [:custom-arrow: Introduction to Wormhole](/docs/learn/introduction/) - -- :octicons-book-16:{ .lg .middle } **Messaging Infrastructure** + Amount being transferred, truncated to 8 decimals. --- - Investigate the messaging protocol architecture with an in-depth exploration of the individual components powering Wormhole's infrastructure. - - [:custom-arrow: Understand Wormhole's infrastructure](/docs/learn/infrastructure/) - -
- -## Multichain Transfers - -Wormhole transfer products offer multiple options to meet your project's needs. Which product is best for your use depends upon the asset transfer type you want to add to your dApp. + `TokenAddress` ++"bytes32"++ -### Wrapped Tokens - -This method is likely familiar to you if you've previously built bridging projects. - -
- -- :octicons-book-16:{ .lg .middle } **Token Bridge** + Address of the token. Left-zero-padded if shorter than 32 bytes. --- - - Use Wormhole deployed contracts to simplify development - - Multichain token transfers through lock-and-mint-mechanism - - Option to include message payload for uses like social platforms - - [:custom-arrow: Learn about Token Bridge](/docs/learn/transfers/token-bridge/) - -
+ `TokenChain` ++"uint16"++ -### Native Tokens + Chain ID of the token. -Eliminate wrapped assets to preserve your token's native properties across chains. + --- -
+ `To` ++"bytes32"++ -- :octicons-book-16:{ .lg .middle } **Native Token Transfers** + Address of the recipient. Must be a contract capable of parsing and handling the payload. Left-zero-padded if shorter than 32 bytes --- - - Deploy custom smart contracts to retain token ownership and upgrade authority with complete customizability - - No wrapped tokens or liquidity pools to avoid slippage and MEV risk - - Custom attestation is available by adding external verifiers - - [:custom-arrow: Learn about Native Token Transfers](/docs/learn/transfers/native-token-transfers/) - -
+ `ToChain` ++"uint16"++ -### Intent-Based Transfers + Chain ID of the recipient. -Institutional-scale digital asset settlement for individual users and insitutions. + --- -
+ `FromAddress` ++"bytes32"++ -- :octicons-book-16:{ .lg .middle } **Settlement** + Address of the sender on the source chain. --- - - Leverages three protocols, providing flexibility and redundancy - - Chain-agnostic to liquidity on chains, enabling broader chain support - - English auction determines the winning solver for settlement - - USDC as the shuttle asset for seamless cross-chain settlement + `Payload` ++"bytes"++ - [:custom-arrow: Learn about Settlement](/docs/learn/transfers/settlement/) + Arbitrary data passed to the recipient contract. Can be used for DeFi operations, authentication, or app-specific logic. -
-## Governance +Unlike `Transfer`, the `TransferWithPayload` message must be redeemed by the recipient contract since only that contract can handle the custom payload properly. -Explore MultiGov, Wormhole's multichain governance solution. +## RegisterChain -
+The `RegisterChain` governance payload (Action ID = `1`) registers a Token Bridge emitter address for a foreign chain. This ensures the bridge only accepts messages from known peers. -- :octicons-book-16:{ .lg .middle } **Multichain Governance** +```text +Module [32]byte +Action uint8 = 1 +ChainId uint16 - --- +EmitterChainID uint16 +EmitterAddress [32]uint8 +``` - - Multichain voting and proposal execution - - Aggregates votes from all chains - - Can integrate with any Wormhole-supported blockchain +??? interface "Parameters" - [:custom-arrow: Learn about MultiGov](/docs/learn/governance/) + `Module` ++"[32]byte"++ -
+ Module identifier. Left-padded with `TokenBridge` for Token Bridge. -## Additional Resources + --- -
+ `Action` ++"uint8"++ -- :octicons-book-16:{ .lg .middle } **Product Comparison** + Value must be `1`, indicating a `RegisterChain` operation. --- - Compare Wormhole's multichain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. + `ChainID` ++"uint16"++ - [:custom-arrow: Compare Products](/docs/build/start-building/products/){target=\_blank} - -- :octicons-book-16:{ .lg .middle } **Use Cases** + The chain where this governance action should be applied. `0` is a valid value for all chains --- - Explore Wormhole's use cases, from multichain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. + `EmitterChainID` ++"uint16"++ - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) + Chain ID of the registered emitter. -
---- END CONTENT --- + --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/architecture/ ---- BEGIN CONTENT --- ---- -title: Architecture -description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -categories: Basics ---- + `EmitterAddress` ++"[32]uint8"++ -# Architecture + Address of the registered emitter, left-zero-padded if shorter than 32 bytes. -## Overview +This payload can only be emitted by the Wormhole governance contract, ensuring that each chain accepts messages only from one verified bridge emitter per remote chain. -Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. +## UpgradeContract -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +The `UpgradeContract` governance payload (Action ID = `2`) facilitates upgrades to the Token Bridge contract on a specific chain. -The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: +```text +Module [32]byte +Action uint8 = 2 +ChainId uint16 -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} -3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain -4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. +NewContract [32]uint8 +``` - The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: +??? interface "Parameters" - - In some applications, the target contract acts as the entry point and performs verification via the Core Contract - - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract + `Module` ++"[32]byte"++ -## On-Chain Components + Module identifier, left-padded with `TokenBridge` for Token Bridge. -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication -- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract + --- -## Off-Chain Components + `Action` ++"uint8"++ -- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution -- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers + Value must be `2`, indicating an `UpgradeContract` operation. -## Next Steps + --- -
+ `ChainID` ++"uint16"++ -- :octicons-book-16:{ .lg .middle } **Core Contracts** + The target chain where the governance action should be applied. --- - Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + `NewContract` ++"[32]uint8"++ -- :octicons-tools-16:{ .lg .middle } **Core Messaging** - - --- + Address of the new Token Bridge contract, left-zero-padded to 32 bytes. - Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. +This message allows the Wormhole governance system to deploy new versions of the bridge while retaining control over interoperability and security. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) +## Summary of Payload Structure -
+| Payload Type | ID | Purpose | Who Emits It | +|-----------------------|---------------|------------------------------------------------------------------------|------------------------| +| `Transfer` | PayloadID `1` | Moves tokens between chains by minting or releasing on the destination | Token Bridge contract | +| `AssetMeta` | PayloadID `2` | Attests token metadata (decimals, symbol, name) before first transfer | Token Bridge contract | +| `TransferWithPayload` | PayloadID `3` | Transfers tokens along with a custom payload for contract execution | Token Bridge contract | +| `RegisterChain` | Action `1` | Registers a verified Token Bridge emitter for a foreign chain | Wormhole governance | +| `UpgradeContract` | Action `2` | Upgrades the Token Bridge contract on a specific chain | Wormhole governance | --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/core-contracts/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/concepts/transfer-flow/ --- BEGIN CONTENT --- --- -title: Core Contracts -description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -categories: Basics +title: Flow of a Token Bridge Transfer +description: Learn how the Wormhole Token Bridge enables secure, cross-chain token transfers by combining token-specific logic with Wormhole's core message-passing layer. +categories: Token-Bridge, Transfer --- -# Core Contracts +# Flow of a Transfer ## Introduction -The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. - -This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. - -## Key Functions - -Key functions of the Wormhole Core Contract include the following: - -- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network -- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered -- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability -- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time - -## How the Core Contract Works - -The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. - -The following describes the role of the Wormhole Core Contract in message transfers: - -1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification -2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions - -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. - -### Message Submission +The [Wormhole Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} enables token transfers across blockchains by combining token-specific logic with [Wormhole's core messaging layer](/docs/protocol/architecture/){target=\_blank}. Each supported chain runs its own Token Bridge contract, which manages actions like locking, burning, minting, and releasing tokens. These contracts communicate directly with Wormhole's core message-passing layer to securely transmit messages between chains. -You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: +This guide provides a conceptual overview of the Token Bridge and its integration with the messaging layer. It outlines each step of the transfer flow and explains how different transfer types work in practice. -- `emitterAddress` - the contract which made the call to publish the message -- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page +## Transfer Flow -There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. +Cross-chain token transfers using the Token Bridge follow these steps: -### Message Reception +1. **Initiation on the Source Chain** + The transfer begins when a user calls the Token Bridge contract on the source chain: -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. + - **Wrapped tokens**: The token is burned. + - **Original tokens**: If the token is native to the source chain, the token is locked in the contract. -## Multicast +2. **Transfer Message Publication** + The Token Bridge contract invokes the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}, which emits an on-chain message event describing the transfer. -Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. +3. **Message Observation and Signing** + [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}—a decentralized network of validators—monitor the source chain for these message events. A supermajority (13 out of 19) signs the event to generate a [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}—a cryptographically signed attestation of the transfer. -This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. + The VAA is then published to the Wormhole network. -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. +4. **VAA Submission to the Destination Chain** + The VAA must be submitted to the Token Bridge contract on the destination chain to complete the transfer. The Token Bridge contract then verifies the VAA by calling the Core Contract behind the scenes. This step can be handled in two ways: -Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. + - **Automatic**: A relayer service detects the VAA and submits it to the Token Bridge contract. + - **Manual**: The user or dApp retrieves the VAA and submits it directly to the Token Bridge contract. -## Next Steps +5. **Finalization of the Transfer on the Destination Chain** + After the VAA is verified on the destination chain, the Token Bridge contract completes the transfer: -
+ - **Wrapped tokens**: A wrapped representation of the original token is minted. + - **Original tokens**: If the token is native to the destination chain, the token is released to the recipient. -- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** +Consider this example: Alice wants to send 5 ETH from Ethereum to Solana. The ETH is locked on Ethereum’s Token Bridge, and an equivalent amount of wrapped ETH is minted on Solana. The diagram below illustrates this transfer flow. - --- +```mermaid +sequenceDiagram + participant Alice as Alice + participant TokenBridgeEth as Token Bridge Ethereum
(Source Chain) + participant CoreEth as Core Contract Ethereum
(Source Chain) + participant Guardians + participant TokenBridgeSol as Token Bridge Solana
(Destination Chain) + participant CoreSol as Core Contract Solana
(Destination Chain) - Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. + Alice->>TokenBridgeEth: Initiate ETH transfer
(lock ETH) + TokenBridgeEth->>CoreEth: Publish transfer message + CoreEth-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + alt Automatic VAA submission + Guardians->>TokenBridgeSol: Relayer submits VAA + else Manual VAA submission + Alice->>Guardians: Retrieve VAA + Alice->>TokenBridgeSol: Submit VAA + end -- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** + TokenBridgeSol->>CoreSol: Verify VAA + CoreSol-->>TokenBridgeSol: VAA verified + TokenBridgeSol-->>Alice: Mint wrapped ETH on Solana (complete transfer) +``` - --- +Maybe Alice wants to transfer her wrapped ETH on Solana back to native ETH on Ethereum. The wrapped ETH is burned on Solana’s Token Bridge, and the equivalent 5 ETH are released on Ethereum. The diagram below illustrates this transfer flow. + +```mermaid +sequenceDiagram + participant User as Alice + participant TokenBridgeSrc as Token Bridge Solana
(Source Chain) + participant CoreSrc as Core Contract Solana
(Source Chain) + participant Guardians + participant TokenBridgeDst as Token Bridge Ethereum
(Destination Chain) + participant CoreDst as Core Contract Ethereum
(Destination Chain) + + User->>TokenBridgeSrc: Initiate transfer
(burn wrapped ETH) + TokenBridgeSrc->>CoreSrc: Publish message + CoreSrc-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA + + alt Automatic VAA submission + Guardians->>TokenBridgeDst: Relayer submits VAA + else Manual VAA submission + User->>Guardians: Retrieve VAA + User->>TokenBridgeDst: User submits VAA directly + end + + TokenBridgeDst->>CoreDst: Verify VAA + CoreDst-->>TokenBridgeDst: VAA verified + TokenBridgeDst-->>User: Release native ETH on Ethereum (Complete transfer) +``` - This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) +## Automatic vs. Manual Transfers -
---- END CONTENT --- +The Token Bridge supports two modes of transfer, depending on whether the VAA submission step is handled automatically or manually: -Doc-Content: https://wormhole.com/docs/learn/infrastructure/guardians/ ---- BEGIN CONTENT --- ---- -title: Guardians -description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -categories: Basics ---- +- **Automatic**: A relayer service listens for new VAAs and automatically submits them to the destination chain. +- **Manual**: The user (or dApp) must retrieve the VAA and manually submit it to the destination chain. -## Guardian +Here's a quick breakdown of the key differences: -Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. +| Feature | Automatic Transfer | Manual Transfer | +|---------------------------|-----------------------------|-------------------------------------| +| Who submits the VAA? | Relayer | User or dApp | +| User Experience | Seamless, one-step | Requires manual intervention | +| Best for | End-users, simple UIs | Custom dApps, advanced control | +| Dependency | Requires relayer support | None | -Guardians fulfill their role in the messaging protocol as follows: +### Completing Manual Transfers -1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians -2. Guardians combine their independent signatures to form a multisig -3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state +The user who initiated the transfer should complete the transfer within 24 hours for manual transfers. Guardian Sets are guaranteed to be valid for at least that long. If a user waits longer, the Guardian Set may have changed between initiation and redemption, causing the VAA to be rejected. -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +If this occurs, follow the [Replace Outdated Signatures in VAAs](){target=_blank} tutorial to update the VAA with signatures from the current Guardian Set. -## Guardian Network +## Token Bridge Relayer (TBR) -The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. +When completing an automatic transfer using the Token Bridge—either through [Connect](/docs/products/connect/overview/){target=\_blank} or programmatically via the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}—the Token Bridge Relayer (TBR) manages the interaction with the underlying Token Bridge contracts on [supported chains where the TBR is available](/docs/products/connect/reference/support-matrix/){target=\_blank}. -The Guardian Network is designed to help Wormhole deliver on five key principles: + -- **Decentralization** - control of the network is distributed across many parties -- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability -- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network -- **Scalability** - can handle large transaction volumes and high-value transfers -- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing +### Flow of an Automatic Transfer via TBR -The following sections explore each principle in detail. +The flow of an automatic transfer using the TBR looks like this: -### Decentralization +1. **Initiation on the Source Chain** + The transfer begins when a user initiates a transfer on the source chain, which results in the TBR contract being called. -Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. +2. **Prepare and Forward the Transfer** + The TBR verifies the token, encodes transfer details (relayer fee, native gas request, recipient), and forwards the transfer to the Token Bridge. -Two common approaches to decentralization have notable limitations: +3. **Core Messaging Layer Processes the Transfer** + The Token Bridge emits a message to the Core Contract. Guardians observe the message and produce a signed VAA attesting to the transfer. -- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve -- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment +4. **Off-Chain Relayer Observes the VAA** -In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. + An off-chain relayer verifies the destination chain and token registration and then prepares to complete the transfer. -If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? +5. **Relayer Computes Native Drop-Off and Submits the VAA** -To answer that, consider these key constraints and design decisions: + The relayer queries the destination TBR for the native gas amount, includes it in the transaction, and submits the signed VAA. -- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system -- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen -- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security -- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants +6. **TBR Validates and Completes the Transfer** + + The destination TBR validates the VAA by invoking the Token Bridge contract, confirms it's from a registered TBR, verifies the token and native gas request, and then takes custody of the tokens. -This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. +6. **Asset Distribution on the Destination Chain** -### Modularity + The TBR sends the remaining tokens and native gas to the user, pays the off-chain relayer fee, and refunds any excess native tokens. -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +The following diagram illustrates the key steps on the source chain during a transfer: -### Chain Agnosticism +```mermaid +sequenceDiagram + participant User + participant SourceTBR as Source Chain TBR + participant SourceTB as Source Chain Token Bridge + participant Messaging as Core Messaging Layer -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. + User->>SourceTBR: Initiate transfer (token,
recipient, fees, native gas) + SourceTBR->>SourceTB: Forward transfer (burn or lock tokens) + SourceTB->>Messaging: Publish transfer message +``` -### Scalability +Once the core messaging layer processes the transfer, the destination chain handles completion as shown below: + +```mermaid +sequenceDiagram + participant Messaging as Core Messaging Layer + participant Relayer as Off-chain Relayer + participant DestTBR as Destination Chain TBR + participant DestTB as Destination Chain
Token Bridge + participant DestUser as User
(Destination Chain) + + Messaging->>Relayer: Emit signed VAA for transfer + Relayer->>Relayer: Verifies destination chain and token registration + Relayer->>DestTBR: Query native gas amount + Relayer->>DestTBR: Submit signed VAA + DestTBR->>DestTB: Validate VAA + DestTBR->>DestTBR: Take custody of tokens + DestTBR->>DestUser: Send tokens (after fees & native gas) + DestTBR->>Relayer: Pay relayer fee & refund excess +``` -Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. +## Next Steps -Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. +Now that you’ve seen how a transfer works try both types yourself to experience the full process: -Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. +- [Get Started with Token Bridge](/docs/products/token-bridge/get-started/){target=\_blank} +--- END CONTENT --- -### Upgradeable +Doc-Content: https://wormhole.com/docs/products/token-bridge/faqs/ +--- BEGIN CONTENT --- +--- +title: Token Bridge FAQs +description: Find answers to common questions about the Wormhole Token Bridge, including managing wrapped assets and understanding gas fees. +categories: Token-Bridge, Transfer +--- -Wormhole is designed to adapt and evolve in the following ways: +# FAQs -- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set -- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model +## Can ownership of wrapped tokens be transferred from the Token Bridge? -These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. +No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. -## Next Steps + - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself + - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge -
+The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. -- :octicons-book-16:{ .lg .middle } **Relayers** +Relevant contracts: - --- + - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} + - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} + - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} - Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +## How do I update the metadata of a wrapped token? - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) +Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. -- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** +## How do I calculate the current gas costs for Ethereum Mainnet VAA verification? - --- +You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. - Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. +## How can I update my wrapped token image on Solscan? - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) +Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. -
+To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/get-started/ --- BEGIN CONTENT --- --- -title: Infrastructure Components -description: Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -categories: Basics +title: Get Started with Token Bridge +description: Perform token transfers using Wormhole’s Token Bridge with the TypeScript SDK, including manual (Solana–Sepolia) and automatic (Fuji–Alfajores). +categories: Token-Bridge, Transfers --- -# Infrastructure Components - -This section examines the core components that power Wormhole's infrastructure, including Guardians, relayers, VAAs, and the Spy. +# Get Started with Token Bridge -## Get Started +## Introduction -Start here for an overview of Wormhole architecture components and security mechanisms: +Wormhole's [Token Bridge](/docs/products/token-bridge/overview){target=\_blank} enables seamless multichain token transfers by locking tokens on a source chain and minting equivalent wrapped tokens on a destination chain. This mechanism preserves token properties such as name, symbol, and decimal precision across chains. -
+In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform two types of transfers. -- :octicons-book-16:{ .lg .middle } **Architecture Overview** + - **Manual transfer**: Where you control each step. + - **Automatic transfer**: Where a relayer finalizes the transfer for you. - --- +These examples will help you understand how the Token Bridge works across EVM and non-EVM chains. - Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +## Prerequisites - [:custom-arrow: Learn About Architecture](/docs/learn/infrastructure/architecture/) +Before you begin, make sure you have the following: -- :octicons-book-16:{ .lg .middle } **Security** + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank} - --- +This guide uses a Solana wallet with [devnet SOL](https://faucet.solana.com/){target=\_blank} and an EVM wallet with [Sepolia ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank} for the manual transfer example, and [Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} wallets funded with testnet tokens for the automatic transfer. You can adapt the examples to match your preferred chains. - Explore Wormhole's security features, including the Guardian network, governance, and monitoring. +## Configure Your Token Transfer Environment - [:custom-arrow: Learn About Security](/docs/learn/security/) +1. Create a new directory and initialize a Node.js project: -
+ ```bash + mkdir token-bridge + cd token-bridge + npm init -y + ``` -## Explore Components +2. Install the required dependencies: -The relationship between individual components can be demonstrated through the simplified flow of a multichain message from a source-chain contract to a target-chain contract. Select the title of each step to learn more about that component: + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` -[timeline left(wormhole-docs/.snippets/text/learn/infrastructure/infrastructure-index-timeline.json)] +3. Create a `transfer.ts` file to handle the multichain transfer logic, and a `helper.ts` file to manage wallet signers and token utilities: -The [Spy](/docs/learn/infrastructure/spy/) continuously runs in the background to subscribe to gossiped messages across the Guardian Network and enable real-time network activity monitoring. + ```bash + touch transfer.ts helper.ts + ``` -## Next Steps +4. Set up secure access to your wallets. This guide assumes you are loading your `SOL_PRIVATE_KEY` and `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. -
+ !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. -- :octicons-book-16:{ .lg .middle } **Messaging Components** +## Perform a Token Transfer - --- +This section shows how to run manual and automatic token transfers using a shared project structure. You will define helper utilities once and reuse them across both flows. - Learn more about individual messaging components such as Core Contracts, VAAs, Guardians, and relayers +In the manual transfer, you initiate a transfer on Solana, wait for Guardian signatures, and redeem the tokens on Sepolia, giving you complete control over each step. In the automatic transfer, the relayer handles attestation and redemption, simplifying the process between EVM chains. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +1. Open `helper.ts` and define utility functions to load private keys, instantiate signers for Solana and EVM chains, and retrieve token decimals as needed: -- :octicons-people-16:{ .lg .middle } **Core Messaging Guides** + ```ts title="helper.ts" + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, + isTokenId, + TokenId, +} from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; - --- - - Explore this section for guides to using Wormhole Relayer and Core Contracts in your project. +/** + * Returns a signer for the given chain using locally scoped credentials. + * The required values (EVM_PRIVATE_KEY, SOL_PRIVATE_KEY, SUI_MNEMONIC) must + * be loaded securely beforehand, for example via a keystore, secrets + * manager, or environment variables (not recommended). + */ +export async function getSigner( + chain: ChainContext +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + switch (platform) { + case 'Evm': + signer = await ( + await evm() + ).getSigner(await chain.getRpc(), EVM_PRIVATE_KEY!); + break; + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), SOL_PRIVATE_KEY!); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), SUI_MNEMONIC!); + break; + default: + throw new Error(`Unsupported platform: ${platform}`); + } -
---- END CONTENT --- + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} -Doc-Content: https://wormhole.com/docs/learn/infrastructure/relayer/ ---- BEGIN CONTENT --- ---- -title: Relayers -description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -categories: Basics ---- +/** + * Get the number of decimals for the token on the source chain. + * This helps convert a user-friendly amount (e.g., '1') into raw units. + */ +export async function getTokenDecimals( + wh: Wormhole, + token: TokenId, + chain: ChainContext +): Promise { + return isTokenId(token) + ? Number(await wh.getDecimals(token.chain, token.address)) + : chain.config.nativeTokenDecimals; +} + + ``` -# Relayers +2. In `transfer.ts`, add the script for your preferred transfer mode. The `automatic` flag controls transfer behavior passed to `tokenTransfer()`; set it to `false` for manual transfers and `true` for automatic transfers -This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. + === "Manual Transfer" -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. + ```ts title="transfer.ts" + import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; -There are three primary types of relayers discussed: +(async function () { + // Initialize Wormhole SDK for Solana and Sepolia on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); -- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved + // Define the source and destination chains + const sendChain = wh.getChain('Solana'); + const rcvChain = wh.getChain('Sepolia'); -- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Solana', 'native'); + const amt = '0.1'; -## Fundamentals + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); -This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. + // Set to false to require manual approval steps + const automatic = false; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; -Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); -Key characteristics of VAAs include: + // Initiate the transfer from Solana + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); -- Public emission from the Guardian Network + // Wait for the signed attestation from the Guardian network + console.log('Fetching Attestation'); + const timeout = 5 * 60 * 1000; // 5 minutes + await xfer.fetchAttestation(timeout); -- Authentication through signatures from the Guardian Network + // Redeem the tokens on Sepolia + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(destination.signer); + console.log(`Completed Transfer: `, destTxids); -- Verifiability by any entity or any Wormhole Core Contract + process.exit(0); +})(); + ``` + + === "Automatic Transfer" -These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. + ```ts title="transfer.ts" + import { wormhole, amount, Wormhole } from '@wormhole-foundation/sdk'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import evm from '@wormhole-foundation/sdk/evm'; +import { getSigner, getTokenDecimals } from './helper'; -Keep in mind the following security considerations around relayers: +(async function () { + // Initialize Wormhole SDK for Avalanche and Celo on Testnet + const wh = await wormhole('Testnet', [solana, sui, evm]); -- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks + // Define the source and destination chains + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Celo'); -- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly + // Load signers and addresses from helpers + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain + // Define the token and amount to transfer + const tokenId = Wormhole.tokenId('Avalanche', 'native'); + const amt = '0.2'; -## Client-Side Relaying + // Convert to raw units based on token decimals + const decimals = await getTokenDecimals(wh, tokenId, sendChain); + const transferAmount = amount.units(amount.parse(amt, decimals)); -Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. + // Set to false to require manual approval steps + const automatic = true; + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; -### Key Features + // Construct the transfer object + const xfer = await wh.tokenTransfer( + tokenId, + transferAmount, + source.address, + destination.address, + automatic, + undefined, + nativeGas + ); -- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs + // Initiate the transfer from Avalanche Fuji + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(source.signer); + console.log(`Started Transfer: `, srcTxids); -- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure + process.exit(0); +})(); + ``` -### Implementation -Users themselves carry out the three steps of the cross-chain process: +3. Execute the script to initiate and complete the transfer: -1. Perform an action on chain A + ```bash + npx tsx transfer.ts + ``` -2. Retrieve the resulting VAA from the Guardian Network + If successful, the expected output should be similar to this: -3. Perform an action on chain B using the VAA +
+npx tsx transfer.ts +Starting Transfer +Started Transfer: ['36UwBBh6HH6wt3VBbNNawMd1ijCk28YgFePrBWfE3vGQFHtbMjY5626nqHubmyQWGNh2ZrN1vHKRrSQDNC3gkZgB'] + +Getting Attestation +Retrying Wormholescan:GetVaaBytes, attempt 0/900 +Retrying Wormholescan:GetVaaBytes, attempt 1/900 +Retrying Wormholescan:GetVaaBytes, attempt 2/900 + +Completing Transfer +Completed Transfer: [ '53Nt4mp2KRTk2HFyvUcmP9b6cRXjVAN3wCksoBey9WmT' ] + +
-### Considerations +To verify the transaction and view its details, copy the transaction hash from the output and paste it into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. -Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. +## Next Steps -- Users must sign all required transactions with their own wallet +Now that you've completed a manual multichain token transfer, explore these guides to continue building: -- Users must have funds to pay the transaction fees on every chain involved + - [Complete Token Transfer Workflow](/docs/products/token-bridge/tutorials/transfer-workflow){target=\_blank}: Build a reusable application that supports multiple chain combinations and transfer modes (manual and automatic). + - [Create Multichain Tokens](/docs/products/token-bridge/tutorials/multichain-token){target=\_blank}: Learn how to issue tokens that work across chains. +--- END CONTENT --- -- The user experience may be cumbersome due to the manual steps involved +Doc-Content: https://wormhole.com/docs/products/token-bridge/guides/token-bridge-contracts/ +--- BEGIN CONTENT --- +--- +title: Get Started with Token Bridge +description: Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. +categories: Token-Bridge, Transfer +--- -## Custom Relayers +# Interact with Token Bridge Contracts -Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. +## Introduction -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/protocol/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. -### Key Features +This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} page in the Learn section. -- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs +## Prerequisites -- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more +To interact with the Wormhole Token Bridge, you'll need the following: -- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application +- [The address of the Token Bridge contract](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers -- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience +## How to Interact with Token Bridge Contracts -### Implementation +The primary functions of the Token Bridge contracts revolve around: -A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. +- **Attesting a token** - registering a new token for cross-chain transfers +- **Transferring tokens** - locking and minting tokens across chains +- **Transferring tokens with a payload** - including additional data with transfers -### Considerations +### Attest a Token -Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." +Suppose a token has never been transferred to the target chain before transferring it cross-chain. In that case, its metadata must be registered so the Token Bridge can recognize it and create a wrapped version if necessary. -- Development work and hosting of relayers are required +The attestation process doesn't require you to manually input token details like name, symbol, or decimals. Instead, the Token Bridge contract retrieves these values from the token contract itself when you call the `attestToken()` method. -- The fee-modeling can become complex, as relayers are responsible for paying target chain fees +```solidity +function attestToken( + address tokenAddress, + uint32 nonce +) external payable returns (uint64 sequence); +``` -- Relayers are responsible for availability, and adding dependencies for the cross-chain application +??? interface "Parameters" -## Wormhole Relayers + `tokenAddress` ++"address"++ + + The contract address of the token to be attested. -Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. + --- -### Key Features + `nonce` ++"uint32"++ -- **Lower operational costs** - no need to develop, host, or maintain individual relayers + An arbitrary value provided by the caller to ensure uniqueness. -- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface +??? interface "Returns" -### Implementation + `sequence` ++"uint64"++ + + A unique identifier for the attestation transaction. -The Wormhole relayer integration involves two key steps: +??? interface "Example" -- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); -- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA +uint256 wormholeFee = wormhole.messageFee(); -### Considerations +tokenBridge.attestToken{value: wormholeFee}( + address(tokenImpl), // the token contract to attest + 234 // nonce for the transfer +); + ``` -Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. +When `attestToken()` is called, the contract emits a Verifiable Action Approval (VAA) containing the token's metadata, which the Guardians sign and publish. -- All computations are performed on-chain +You must ensure the token is ERC-20 compliant. If it does not implement the standard functions, the attestation may fail or produce incomplete metadata. -- Potentially less gas-efficient compared to custom relayers +### Transfer Tokens -- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted +Once a token is attested, a cross-chain token transfer can be initiated following the lock-and-mint mechanism. On the source chain, tokens are locked (or burned if they're already a wrapped asset), and a VAA is emitted. On the destination chain, that VAA is used to mint or release the corresponding amount of wrapped tokens. -- Support may not be available for all chains +Call `transferTokens()` to lock/burn tokens and produce a VAA with transfer details. -## Next Steps +```solidity +function transferTokens( + address token, + uint256 amount, + uint16 recipientChain, + bytes32 recipient, + uint256 arbiterFee, + uint32 nonce +) external payable returns (uint64 sequence); +``` -
+??? interface "Parameters" -- :octicons-book-16:{ .lg .middle } **Spy** + `token` ++"address"++ + + The address of the token being transferred. --- - Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. + `amount` ++"uint256"++ + The amount of tokens to be transferred. - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) + --- -- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** + `recipientChain` ++"uint16"++ + The Wormhole chain ID of the destination chain. --- - Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. + `recipient` ++"bytes32"++ + The recipient's address on the destination chain. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) + --- -- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** + `arbiterFee` ++"uint256"++ + Optional fee to be paid to an arbiter for relaying the transfer. --- - Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) + `nonce` ++"uint32"++ + A unique identifier for the transaction. -
---- END CONTENT --- +??? interface "Returns" -Doc-Content: https://wormhole.com/docs/learn/infrastructure/spy/ ---- BEGIN CONTENT --- ---- -title: Spy -description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -categories: Basics ---- - -# Spy + `sequence` ++"uint64"++ + + A unique identifier for the transfer transaction. -In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. +??? interface "Example" -The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); -This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); -## Key Features +tokenBridge.transferTokens{value: wormholeFee}( + token, // address of the ERC-20 token to transfer + amount, // amount of tokens to transfer + recipientChain, // Wormhole chain ID of the destination chain + recipient, // recipient address on the destination chain (as bytes32) + arbiterFee, // fee for relayer + nonce // nonce for this transfer +); + ``` -- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time -- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest -- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services -- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity -- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure +Once a transfer VAA is obtained from the Wormhole Guardian network, the final step is to redeem the tokens on the destination chain. Redemption verifies the VAA's authenticity and releases (or mints) tokens to the specified recipient. To redeem the tokens, call `completeTransfer()`. -## Integrator Use Case +```solidity +function completeTransfer(bytes memory encodedVm) external; +``` -The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. +??? interface "Parameters" -This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. + `encodedVm` ++"bytes memory"++ + + The signed VAA containing the transfer details. -## Observable Message Categories +!!!note + - The Token Bridge normalizes token amounts to 8 decimals when passing them between chains. Make sure your application accounts for potential decimal truncation + - The VAA ensures the integrity of the message. Only after the Guardians sign the VAA can it be redeemed on the destination chain -A Spy can access the following categories of messages shared over the gossip protocol: +### Transfer Tokens with Payload -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +While a standard token transfer moves tokens between chains, a transfer with a payload allows you to embed arbitrary data in the VAA. This data can be used on the destination chain to execute additional logic—such as automatically depositing tokens into a DeFi protocol, initiating a swap on a DEX, or interacting with a custom smart contract. - - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification +Call `transferTokensWithPayload()` instead of `transferTokens()` to include a custom payload (arbitrary bytes) with the token transfer. -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +```solidity +function transferTokensWithPayload( + address token, + uint256 amount, + uint16 recipientChain, + bytes32 recipient, + uint32 nonce, + bytes memory payload +) external payable returns (uint64 sequence); +``` - - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events +??? interface "Parameters" -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status + `token` ++"address"++ + + The address of the token being transferred. - - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network + --- -## Additional Resources + `amount` ++"uint256"++ + The amount of tokens to be transferred. -
+ --- -- :octicons-code-16:{ .lg .middle } **Spy Source Code** + `recipientChain` ++"uint16"++ + The Wormhole chain ID of the destination chain. --- - To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. + `recipient` ++"bytes32"++ + The recipient's address on the destination chain. - [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} + --- -- :octicons-code-16:{ .lg .middle } **Alternative Implementation** + `nonce` ++"uint32"++ + A unique identifier for the transaction. --- - Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. + `payload` ++"bytes memory"++ + Arbitrary data payload attached to the transaction. - [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) +??? interface "Returns" + + `sequence` ++"uint64"++ + + A unique identifier for the transfer transaction. -- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** +??? interface "Example" - --- + ```solidity + IWormhole wormhole = IWormhole(wormholeAddr); +ITokenBridge tokenBridge = ITokenBridge(tokenBridgeAddr); - For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. +// Get the fee for publishing a message +uint256 wormholeFee = wormhole.messageFee(); - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) +tokenBridge.transferTokensWithPayload{value: wormholeFee}( + token, // address of the ERC-20 token to transfer + amount, // amount of tokens to transfer + recipientChain, // Wormhole chain ID of the destination chain + recipient, // recipient address on the destination chain (as bytes32) + nonce, // nonce for this transfer + additionalPayload // additional payload data +); + ``` -
+After initiating a transfer on the source chain, the Wormhole Guardian network observes and signs the resulting message, creating a Verifiable Action Approval (VAA). You'll need to fetch this VAA and then call `completeTransferWithPayload()`. -## Next Steps +Only the designated recipient contract can redeem tokens. This ensures that the intended contract securely handles the attached payload. On successful redemption, the tokens are minted (if foreign) or released (if native) to the recipient address on the destination chain. For payload transfers, the designated contract can execute the payload's logic at this time. -
+```solidity +function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory); +``` -- :octicons-code-16:{ .lg .middle } **Run a Spy** +??? interface "Parameters" - --- + `encodedVm` ++"bytes memory"++ - Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). + The signed VAA containing the transfer details. - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} +??? interface "Returns" -- :octicons-code-16:{ .lg .middle } **Use Queries** + `bytes memory` - --- + The extracted payload data. - For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. +## Source Code References - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) +For a deeper understanding of the Token Bridge implementation and to review the actual source code, please refer to the following links: -
+- [Token Bridge contract](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol){target=\_blank} +- [Token Bridge interface](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} + +## Portal Bridge + +A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/infrastructure/vaas/ +Doc-Content: https://wormhole.com/docs/products/token-bridge/overview/ --- BEGIN CONTENT --- --- -title: VAAs -description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. -categories: Basics +title: Token Bridge Overview +description: With Wormhole Token Bridge, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Token-Bridge, Transfer --- -# Verified Action Approvals +# Token Bridge Overview -Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. +The Token Bridge is a Wormhole module for bridging wrapped tokens across various blockchain networks. Locking assets on one network and minting corresponding wrapped tokens on another facilitates secure, efficient, and composable multichain token movement. -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +This overview covers Token Bridge's main features, general processes, and possible next steps to begin building a cross-chain application. -The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. +## Key Features -VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. +Token Bridge is built to solve interoperability problems in multichain token transfers. Key features include: -The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. - -The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. +- **Interoperability**: Transfer standards-compliant tokens (e.g., ERC-20, SPL) across over 30 [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank}. +- **Lock-and-mint mechanism**: Mint wrapped tokens backed 1:1 by locked assets on the source chain. +- **Preserved metadata**: Ensure that token properties like name, symbol, and decimals persist across chains. +- **Transfer with payload**: Attach arbitrary data to token transfers, enabling the triggering of specific actions. +- **Decentralized security**: Verified by the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank}, ensuring cross-chain consistency and message authenticity. -## VAA Format +## How It Works -The basic VAA consists of header and body components described as follows: +The Token Bridge provides a reliable foundation for multichain interoperability at scale. The transfer process follows these key steps: -- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far - - `version` ++"byte"++ - the VAA Version - - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing - - `len_signatures` ++"u8"++ - the number of signatures stored - - `signatures` ++"[]signature"++ - the collection of Guardian signatures +1. **Attestation**: The token’s metadata (e.g., symbol, name, decimals) is registered on the destination chain. This step is only required once per token. +2. **Locking**: On the source chain, the native token is locked in a custody account. +3. **Message emission**: The [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} verifies and emits a [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +4. **Verification**: The VAA is submitted and verified on the destination chain to confirm authenticity. +5. **Minting**: A wrapped version of the token is minted (or the native token is released) to the recipient on the destination chain. - Where each `signature` is: +This diagram showcases a simplified flow of Alice bridging ETH from Ethereum to her account on Solana. - - `index` ++"u8"++ - the index of this Guardian in the Guardian set - - `signature` ++"[65]byte"++ - the ECDSA signature +```mermaid +sequenceDiagram + participant Alice + participant Ethereum + participant GuardianNetwork + participant Solana -- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages - - `timestamp` ++"u32"++ - the timestamp of the block this message was published in - - `nonce` ++"u32"++ - - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message - - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract - - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter - - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter - - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on + Alice->>Ethereum: Lock ETH in Token Bridge contract + Ethereum->>GuardianNetwork: Emit transfer message + GuardianNetwork->>GuardianNetwork: Verify and sign message -The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level + GuardianNetwork->>Solana: Submit signed message + Solana->>Solana: Verify message and mint wrapped ETH (WETH) -The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. + Solana->>Alice: Deliver wrapped ETH on Solana +``` -Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. +For a more in-depth understanding of how the Token Bridge works, see the [Flow of a Transfer](/docs/products/token-bridge/concepts/transfer-flow/){target=\_blank} page. -## Consistency and Finality +## Use Cases -The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. +Here are key use cases that highlight the power and versatility of the Token Bridge. -Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. +- **Multichain Rewards and Token Utility in Decentralized Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** -## Signatures + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Transfer tokens between chains. + - [**Messaging**](/docs/products/messaging/overview/): Facilitate the distribution and claiming processes of rewards. -The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. +- **Tokenized Gaming Rewards** -```js -// hash the bytes of the body twice -digest = keccak256(keccak256(body)) -// sign the result -signature = ecdsa_sign(digest, key) -``` + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Handle the underlying lock-and-mint logic securely. + - [**Connect**](/docs/products/connect/overview/): Provide a user-friendly way to move game tokens across chains. -!!!tip "Hash vs. double hash" - Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. - - For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +- **Multichain DeFi Arbitrage** -## Payload Types + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Enables rapid and secure movement of DeFi assets. + - [**Connect**](/docs/products/connect/overview/): Provides a UI widget to onboard users and facilitate seamless multichain swaps within DeFi aggregator platforms. -Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). +## Next Steps -### Token Transfer +If you are looking for more guided practice, take a look at: -Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/): Perform token transfers using the Token Bridge, including manual and automatic transfers. +- [**Complete Token Transfer Flow**](/docs/products/token-bridge/tutorials/transfer-workflow/): Build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains. +- [**Create Multichain Tokens**](/docs/products/token-bridge/tutorials/multichain-token/): Craft a multichain token using Wormhole's Portal Bridge. +--- END CONTENT --- -Transferring tokens from the sending chain to the destination chain requires the following steps: +Doc-Content: https://wormhole.com/docs/products/token-bridge/tutorials/multichain-token/ +--- BEGIN CONTENT --- +--- +title: Create Multichain Tokens +description: Learn how to create a multichain token, bridge tokens across blockchains, and update metadata for seamless multichain interoperability. +--- -1. Lock the token on the sending chain -2. The sending chain emits a message as proof the token lockup is complete -3. The destination chain receives the message confirming the lockup event on the sending chain -4. The token is minted on the destination chain +# Create Multichain Tokens -The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: +## Introduction -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `fee` ++"u256"++ - portion of amount paid to a relayer +Blockchain ecosystems are becoming increasingly interconnected, with assets often needing to exist across multiple networks to maximize their utility and reach. For example, tokens created on one chain may want to expand to others to tap into broader audiences and liquidity pools. -This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. +This guide explains how to create a multichain token—a token that seamlessly bridges across blockchains using the Wormhole protocol. The process is designed to be user-friendly. With just a few steps, your token can become multichain, enabling it to be traded or used on various networks. -Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. +By the end of this tutorial, you'll learn: -### Attestation +- How to register your token for bridging +- How to create a wrapped version of your token +- How to ensure its visibility on blockchain explorers -While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. +Let’s begin with a straightforward, step-by-step process for creating a multichain token and expanding its reach. -To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. +## Register the Token on the Source Chain -The message format for token attestation is as follows: +The first step in creating a multichain token is registering your token on its source chain. This ensures the token is prepared for bridging across blockchains. Follow these steps: -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation -- `token_address` ++"[32]byte"++ - address of the originating token contract -- `token_chain` ++"u16"++ - chain ID of the originating token -- `decimals` ++"u8"++ - number of decimals this token should have -- `symbol` ++"[32]byte"++ - short name of asset -- `name` ++"[32]byte"++ - full name of asset +1. Open the [Portal Bridge](https://portalbridge.com/advanced-tools/#/register){target=\_blank} +2. Select the blockchain where your token is currently deployed (source chain) +3. Connect your wallet by following the on-screen instructions +4. Locate the **Asset** field and paste the token contract address +5. Click **Next** to proceed -#### Attestation Tips +![Source Chain Registration Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-1.webp) -Be aware of the following considerations when working with attestations: +## Register the Token on the Target Chain -- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters +After registering your token on the source chain, the next step is to select the target chain—the blockchain where you want the wrapped version of your token to exist. This step connects your token to its destination network. -- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes +1. Choose the blockchain where you want the token to be bridged (target chain) +2. Connect your wallet to the target chain +3. Click **Next** to finalize the registration process -- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm +![Target Chain Registration Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-2.webp) -- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 +## Send an Attestation +Attestation is a key step in the process. It verifies your token’s metadata, ensuring it is correctly recognized on the target chain’s blockchain explorer (e.g., [Etherscan](https://etherscan.io/){target=\_blank}). -- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer +1. Click **Attest** to initiate the attestation process +2. Approve the transaction in your wallet when prompted -### Token Transfer with Message +![Send Attestation Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-3.webp) -The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: +!!! note + - Attestation is crucial for token metadata to appear correctly on blockchain explorers like Etherscan, allowing users to identify and trust your token + - Ensure you have sufficient funds to cover transaction fees on the target chain -- **`fee` field** - replaced with the `from_address` field -- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior +## Create the Wrapped Token -This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: +The final step is to create the wrapped token on the target chain. This token represents the original asset and enables its use within the target blockchain. -- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message -- `amount` ++"u256"++ - amount of tokens being transferred -- `token_address` ++"u8[32]"++ - address on the source chain -- `token_chain` ++"u16"++ - numeric ID for the source chain -- `to` ++"u8[32]"++ - address on the destination chain -- `to_chain` ++"u16"++ - numeric ID for the destination chain -- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain -- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific +1. Click **Create** to generate the wrapped token +2. Approve the transaction in your wallet when prompted -### Governance +![Create Wrapped Token Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-4.webp) -Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). +Upon successful creation, you will see a confirmation screen displaying key details such as the source chain, target chain, and transaction status. This helps verify that the process was completed correctly. Refer to the image below as an example: -#### Action Structure +![Confirmation Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-5.webp) -Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: +## Additional Steps and Recommendations -- `module` ++"u8[32]"++ - contains a right-aligned module identifier -- `action` ++"u8"++ - predefined governance action to execute -- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains -- `args` ++"any"++ - arguments to the action +After creating your multichain token, there are a few optional but highly recommended steps to ensure the best experience for users interacting with your token. -Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. +### Add Your Token to the Wormhole Metadata List (Legacy) -```js -module: 0x0000000000000000000000000000000000000000000000000000436f7265 -action: 1 -chain: 1 -new_contract: 0x348567293758957162374959376192374884562522281937446234828323 -``` +For legacy compatibility in the [**Advanced Tools**](https://portalbridge.com/advanced-tools/){target=\_blank} section of Portal Bridge, you can request updates to your token metadata. Follow these steps: -#### Actions +1. Join the [Wormhole Discord server](https://discord.com/invite/wormholecrypto){target=\_blank} +2. Submit a request for metadata updates in the appropriate support channel -The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: +!!! note + These updates only apply to the **Advanced Tools** section of Portal Bridge and will not update how your token appears in other Wormhole-powered apps or on blockchain explorers like Etherscan. -- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} -- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} +### Update Metadata on Blockchain Explorers -## Lifetime of a Message +It is recommended that you update your token’s metadata on blockchain explorers such as Etherscan. This includes adding details like the token logo, price, and contract verification. -Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. +1. Create an account on the relevant scanner and go to the [token update section](https://etherscan.io/tokenupdate){target=\_blank} (or the relevant scanner that you would like to update metadata on) +2. Copy and paste the wrapped contract address in the **Token Update Application Form** +3. Before proceeding to the next step, you will need to verify as the contract address owner on [Etherscan’s address verification tool](https://etherscan.io/verifyAddress/){target=\_blank} +4. Follow the directions to verify contract address ownership via MetaMask by reviewing the [guide on verifying address ownership](https://info.etherscan.com/how-to-verify-address-ownership/){target=\_blank} + - Given that Wormhole may be the contract owner, use the manual verification process by reaching out through the [Etherscan contact form](https://etherscan.io/contactus){target=\_blank}. The team will provide support as needed +5. Once the step above is completed, follow the [instructions to update token information](https://info.etherscan.com/how-to-update-token-information-on-token-page/){target=\_blank} +--- END CONTENT --- -With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. +Doc-Content: https://wormhole.com/docs/products/token-bridge/tutorials/transfer-workflow/ +--- BEGIN CONTENT --- +--- +title: Transfer Tokens via Token Bridge Tutorial +description: Learn to build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains +--- -1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians -2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA -3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step +# Complete Token Transfer Workflow -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-ts-sdk/){target=\_blank} -## Next Steps +## Introduction -
+This tutorial guides you through building a cross-chain token transfer application using the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and its [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} method. The Token Bridge method enables secure and efficient cross-chain asset transfers across different blockchain networks, allowing users to move tokens seamlessly. -- :octicons-book-16:{ .lg .middle } **Guardians** +By leveraging Wormhole’s Token Bridge, this guide shows you how to build an application that supports multiple transfer types: - --- + - EVM to EVM (e.g., Ethereum to Avalanche) + - EVM to non-EVM chains (e.g., Ethereum to Solana) + - Non-EVM to EVM chains (e.g., Sui to Avalanche) + - Non-EVM to non-EVM chains (e.g., Solana to Sui) - Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +Existing solutions for cross-chain transfers can be complex and inefficient, requiring multiple steps and transaction fees. However, the Token Bridge method from Wormhole simplifies the process by handling the underlying attestation, transaction validation, and message passing across blockchains. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) +At the end of this guide, you’ll have a fully functional setup for transferring assets across chains using Wormhole’s Token Bridge method. -- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** +## Prerequisites - --- +Before you begin, ensure you have the following: - Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine + - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally + - Native tokens (testnet or mainnet) in Solana and Sui wallets + - A wallet with a private key, funded with native tokens (testnet or mainnet) for gas fees - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) +## Supported Chains -
---- END CONTENT --- +The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains on the [Contract Addresses](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} page, which includes every network where Wormhole smart contracts are deployed, across both mainnet and testnet. -Doc-Content: https://wormhole.com/docs/learn/introduction/ ---- BEGIN CONTENT --- ---- -title: Introduction to Wormhole -description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. -categories: Basics ---- +## Project Setup -# Introduction to Wormhole +In this section, we’ll guide you through initializing the project, installing dependencies, and preparing your environment for cross-chain transfers. -In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. +1. **Initialize the project** - start by creating a new directory for your project and initializing it with `npm`, which will create the `package.json` file for your project -Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. + ```bash + mkdir native-transfers + cd native-transfers + npm init -y + ``` -Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. +2. **Create a `.gitignore` file** - ensure your private key isn't accidentally exposed or committed to version control -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) + ```bash + echo ".env" >> .gitignore + ``` -!!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. +3. **Install dependencies** - install the required dependencies, including the Wormhole SDK and helper libraries -Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. + ```bash + npm install @wormhole-foundation/sdk dotenv tsx + ``` -This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. +4. **Set up environment variables** - to securely store your private key, create a `.env` file in the root of your project -## What Problems Does Wormhole Solve? + ```bash + touch .env + ``` -Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. + Inside the `.env` file, add your private keys. -Critical problems Wormhole addresses include: + ```env + ETH_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" + SOL_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" + SUI_PRIVATE_KEY="INSERT_SUI_MNEMONIC" + ``` -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions + !!! note + Ensure your private key contains native tokens for gas on both the source and destination chains. For Sui, you must provide a mnemonic instead of a private key. -## What Does Wormhole Offer? +5. **Create a `helpers.ts` file** - to simplify the interaction between chains, create a file to store utility functions for fetching your private key, set up signers for different chains, and manage transaction relays -Wormhole provides a suite of tools and protocols that support a wide range of use cases: + 1. Create the helpers file -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently + ```bash + mkdir -p src/helpers + touch src/helpers/helpers.ts + ``` -## What Isn't Wormhole? + 2. Open the `helpers.ts` file and add the following code -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge + ```typescript + import { + ChainAddress, + ChainContext, + Network, + Signer, + Wormhole, + Chain, + TokenId, + isTokenId, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import aptos from '@wormhole-foundation/sdk/aptos'; +import { config } from 'dotenv'; +config(); -## Use Cases of Wormhole +export interface SignerStuff { + chain: ChainContext; + signer: Signer; + address: ChainAddress; +} -Consider the following examples of potential applications enabled by Wormhole: +// Function to fetch environment variables (like your private key) +function getEnv(key: string): string { + const val = process.env[key]; + if (!val) throw new Error(`Missing environment variable: ${key}`); + return val; +} -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +// Signer setup function for different blockchain platforms +export async function getSigner( + chain: ChainContext, + gasLimit?: bigint +): Promise<{ + chain: ChainContext; + signer: Signer; + address: ChainAddress; +}> { + let signer: Signer; + const platform = chain.platform.utils()._platform; -## Explore + switch (platform) { + case 'Solana': + signer = await ( + await solana() + ).getSigner(await chain.getRpc(), getEnv('SOL_PRIVATE_KEY')); + break; + case 'Evm': + const evmSignerOptions = gasLimit ? { gasLimit } : {}; + signer = await ( + await evm() + ).getSigner( + await chain.getRpc(), + getEnv('ETH_PRIVATE_KEY'), + evmSignerOptions + ); + break; + case 'Sui': + signer = await ( + await sui() + ).getSigner(await chain.getRpc(), getEnv('SUI_MNEMONIC')); + break; + case 'Aptos': + signer = await ( + await aptos() + ).getSigner(await chain.getRpc(), getEnv('APTOS_PRIVATE_KEY')); + break; + default: + throw new Error('Unsupported platform: ' + platform); + } -Discover more about the Wormhole ecosystem, components, and protocols: + return { + chain, + signer: signer as Signer, + address: Wormhole.chainAddress(chain.chain, signer.address()), + }; +} -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +export async function getTokenDecimals< + N extends 'Mainnet' | 'Testnet' | 'Devnet' +>( + wh: Wormhole, + token: TokenId, + sendChain: ChainContext +): Promise { + return isTokenId(token) + ? Number(await wh.getDecimals(token.chain, token.address)) + : sendChain.config.nativeTokenDecimals; +} + + ``` -## Demos + - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file + - **`getSigner`** - based on the chain you're working with (EVM, Solana, Sui, etc.), this function retrieves a signer for that specific platform. The signer is responsible for signing transactions and interacting with the blockchain. It securely uses the private key stored in your `.env` file + - **`getTokenDecimals`** - this function fetches the number of decimals for a token on a specific chain. It helps handle token amounts accurately during transfers -Demos offer more realistic implementations than tutorials: +## Check and Create Wrapped Tokens -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +Before tokens are transferred across chains, it should be checked whether a wrapped version exists on the destination chain. If not, an attestation must be generated to wrap it so it can be sent and received on that chain. - +### Configure the Wrapped Token Script -!!! note - Wormhole Integration Complete? - - Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! +1. **Create the `create-wrapped.ts` file** - set up the script file that will handle checking and wrapping tokens in the `src` directory - **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** + ```bash + mkdir -p src/scripts + touch src/scripts/create-wrapped.ts + ``` -## Supported Blockchains +2. **Open `create-wrapped.ts` and import the required modules** - import the necessary SDK modules to interact with Wormhole, EVM, Solana, and Sui chains, as well as helper functions for signing and sending transactions -Wormhole supports a growing number of blockchains. + ```typescript + import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { inspect } from 'util'; +import { getSigner } from '../helpers/helpers'; + ``` -text/supported-networks.md ---- END CONTENT --- +3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support -Doc-Content: https://wormhole.com/docs/learn/security/ ---- BEGIN CONTENT --- ---- -title: Security -description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -categories: Basics ---- + ```typescript + const wh = await wormhole('Testnet', [evm, solana, sui]); + ``` -# Security + !!! note + You can replace `'Testnet'` with `'Mainnet'` if you want to perform transfers on Mainnet. -## Core Security Assumptions +4. **Configure transfer parameters** - specify Arbitrum Sepolia as the source chain and Base Sepolia as the destination, retrieve the token ID from the source chain for transfer, and set the gas limit (optional) -At its core, Wormhole is secured by a network of [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. + ```typescript + const destChain = wh.getChain('BaseSepolia'); + const token = await srcChain.getNativeWrappedTokenId(); + const gasLimit = BigInt(2_500_000); + ``` -- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/learn/glossary/#vaa){target=\_blank}) -- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} -- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator -- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs -- Any Signed VAA can be verified as authentic by the Core Contract of any other chain -- [Relayers](/docs/learn/glossary/#relayer){target=\_blank} are considered untrusted in the Wormhole ecosystem +5. **Set up the destination chain signer** - the signer authorizes transactions, such as submitting the attestation -In summary: + ```typescript + + ``` -- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** -- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on -- You can expand your contract and chain dependencies as you see fit +6. **Check if the token is wrapped on the destination chain** - verify if the token already exists as a wrapped asset before creating an attestation -Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. + ```typescript + try { + const wrapped = await tbDest.getWrappedAsset(token); + console.log( + `Token already wrapped on ${destChain.chain}. Skipping attestation.` + ); + return { chain: destChain.chain, address: wrapped }; + } catch (e) { + console.log( + `No wrapped token found on ${destChain.chain}. Proceeding with attestation.` + ); + } + ``` -## Guardian Network + If the token is already wrapped, the script exits, and you may proceed to the [next section](/docs/products/token-bridge/tutorials/transfer-workflow/#token-transfers). Otherwise, an attestation must be generated. -Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. +7. **Set up the source chain signer** - the signer creates and submits the attestation transaction -### Governance + ```typescript + + ``` -Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. +8. **Create an attestation transaction** - generate and send an attestation for the token on the source chain to register it on the destination chain, then save the transaction ID to verify the attestation in the next step -This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. + ```typescript + const attestTxns = tbOrig.createAttestation( + token.address, + Wormhole.parseAddress(origSigner.chain(), origSigner.address()) + ); -Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. + const txids = await signSendWait(srcChain, attestTxns, origSigner); + console.log('txids: ', inspect(txids, { depth: null })); + const txid = txids[0]!.txid; + console.log('Created attestation (save this): ', txid); + ``` -All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. +9. **Retrieve the signed VAA** - once the attestation transaction is confirmed, use `parseTransaction(txid)` to extract Wormhole messages, then retrieve the signed VAA from the messages. The timeout defines how long to wait for the VAA before failure -Via governance, the Guardians can: + ```typescript + console.log('Parsed Messages:', msgs); -- Change the current Guardian set -- Expand the Guardian set -- Upgrade ecosystem contract implementations + const timeout = 25 * 60 * 1000; + const vaa = await wh.getVaa(msgs[0]!, 'TokenBridge:AttestMeta', timeout); + if (!vaa) { + throw new Error( + 'VAA not found after retries exhausted. Try extending the timeout.' + ); + } + ``` -The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. +10. **Submit the attestation on the destination chain** - submit the signed VAA using `submitAttestation(vaa, recipient)` to create the wrapped token on the destination chain, then send the transaction and await confirmation -## Monitoring + ```typescript + vaa, + Wormhole.parseAddress(destSigner.chain(), destSigner.address()) + ); -A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. + const tsx = await signSendWait(destChain, subAttestation, destSigner); + ``` -Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. +11. **Wait for the wrapped asset to be available** - poll until the wrapped token is available on the destination chain -Guardians monitor: + ```typescript + do { + try { + const wrapped = await tbDest.getWrappedAsset(token); + return { chain: destChain.chain, address: wrapped }; + } catch (e) { + console.error('Wrapped asset not found yet. Retrying...'); + } + console.log('Waiting before checking again...'); + await new Promise((r) => setTimeout(r, 2000)); + } while (true); + } -- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue -- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains -- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators + console.log('Wrapped Asset: ', await waitForIt()); +})().catch((e) => console.error(e)); + ``` -## Asset Layer Protections + If the token is not found, it logs a message and retries after a short delay. Once the wrapped asset is detected, its address is returned. -One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. +??? code "Complete script" + ```typescript + import { Wormhole, signSendWait, wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { inspect } from 'util'; +import { getSigner } from '../helpers/helpers'; -To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. +(async function () { + const wh = await wormhole('Testnet', [evm, solana, sui]); -In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. + // Define the source and destination chains + const srcChain = wh.getChain('ArbitrumSepolia'); + const destChain = wh.getChain('BaseSepolia'); + const token = await srcChain.getNativeWrappedTokenId(); + const gasLimit = BigInt(2_500_000); -## Open Source + // Destination chain signer setup + const { signer: destSigner } = await getSigner(destChain, gasLimit); + const tbDest = await destChain.getTokenBridge(); -Wormhole builds in the open and is always open source. + try { + const wrapped = await tbDest.getWrappedAsset(token); + console.log( + `Token already wrapped on ${destChain.chain}. Skipping attestation.` + ); + return { chain: destChain.chain, address: wrapped }; + } catch (e) { + console.log( + `No wrapped token found on ${destChain.chain}. Proceeding with attestation.` + ); + } -- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** -- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** -- **[Wormhole contract deployments](/docs/learn/infrastructure/core-contracts/){target=\_blank}** + // Source chain signer setup + const { signer: origSigner } = await getSigner(srcChain); -## Audits + // Create an attestation transaction on the source chain + const tbOrig = await srcChain.getTokenBridge(); + const attestTxns = tbOrig.createAttestation( + token.address, + Wormhole.parseAddress(origSigner.chain(), origSigner.address()) + ); -Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: + const txids = await signSendWait(srcChain, attestTxns, origSigner); + console.log('txids: ', inspect(txids, { depth: null })); + const txid = txids[0]!.txid; + console.log('Created attestation (save this): ', txid); -- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} -- [Neodyme](https://neodyme.io/en/){target=\_blank} -- [Kudelski](https://kudelskisecurity.com/){target=\_blank} -- [OtterSec](https://osec.io/){target=\_blank} -- [Certik](https://www.certik.com/){target=\_blank} -- [Hacken](https://hacken.io/){target=\_blank} -- [Zellic](https://www.zellic.io/){target=\_blank} -- [Coinspect](https://www.coinspect.com/){target=\_blank} -- [Halborn](https://www.halborn.com/){target=\_blank} -- [Cantina](https://cantina.xyz/welcome){target=\_blank} + // Retrieve the Wormhole message ID from the attestation transaction + const msgs = await srcChain.parseTransaction(txid); + console.log('Parsed Messages:', msgs); -All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. + const timeout = 25 * 60 * 1000; + const vaa = await wh.getVaa(msgs[0]!, 'TokenBridge:AttestMeta', timeout); + if (!vaa) { + throw new Error( + 'VAA not found after retries exhausted. Try extending the timeout.' + ); + } -## Bug Bounties + console.log('Token Address: ', vaa.payload.token.address); -Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. + // Submit the attestation on the destination chain + console.log('Attesting asset on destination chain...'); -Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. + const subAttestation = tbDest.submitAttestation( + vaa, + Wormhole.parseAddress(destSigner.chain(), destSigner.address()) + ); -If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. + const tsx = await signSendWait(destChain, subAttestation, destSigner); + console.log('Transaction hash: ', tsx); -For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. + // Poll for the wrapped asset until it's available + async function waitForIt() { + do { + try { + const wrapped = await tbDest.getWrappedAsset(token); + return { chain: destChain.chain, address: wrapped }; + } catch (e) { + console.error('Wrapped asset not found yet. Retrying...'); + } + console.log('Waiting before checking again...'); + await new Promise((r) => setTimeout(r, 2000)); + } while (true); + } -## Learn More + console.log('Wrapped Asset: ', await waitForIt()); +})().catch((e) => console.error(e)); + ``` -The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. ---- END CONTENT --- +### Run the Wrapped Token Creation -Doc-Content: https://wormhole.com/docs/learn/transfers/cctp/ ---- BEGIN CONTENT --- ---- -title: Circle's CCTP Bridge -description: Unlock fast USDC transfers with Wormhole's integration of Circle's CCTP, featuring automatic relaying via the Wormhole relayer and native gas solutions. -categories: Transfer ---- +Once the script is ready, execute it with: -# Circle's CCTP Bridge +```bash +npx tsx src/scripts/create-wrapped.ts +``` -Wormhole Connect and the Wormhole TypeScript SDK support fast, cheap, native USDC bridging between all networks supported by Circle's [Cross-Chain Transfer Protocol](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. CCTP is Circle's native USDC cross-chain transfer attestation service. +If the token is already wrapped, the script exits. Otherwise, it generates an attestation and submits it. Once complete, you’re ready to transfer tokens across chains. -While this protocol is wholly separate from Wormhole itself, Wormhole builds on top of CCTP and adds several valuable augmentations, making it more straightforward to use and more useful for end users. These features include: +## Token Transfers -- **Automated relaying** - eliminates the need for users to redeem USDC transfers themselves -- **Gas payment on the destination chain** - allows users to transfer USDC without needing to pay gas on the destination chain -- **Gas drop off** - enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer +In this section, you'll create a script to transfer native tokens across chains using Wormhole's Token Bridge method. The script will handle the transfer of Sui native tokens to Solana, demonstrating the seamless cross-chain transfer capabilities of the Wormhole SDK. Since both chains are non-EVM compatible, you'll need to manually handle the attestation and finalization steps. -!!! note - Wormhole supports all CCTP-supported chains but at the moment only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank} are supported by Circle. +### Configure Transfer Details -You can use Wormhole's CCTP-powered USDC bridging by embedding the [Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or by integrating the [TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} directly. +Before initiating a cross-chain transfer, you must set up the chain context and signers for both the source and destination chains. -## Automatic Relaying +1. Create the `native-transfer.ts` file in the `src` directory to hold your script for transferring native tokens across chains -To complete a CCTP transfer, the [Circle Attestation](https://developers.circle.com/api-reference/stablecoins/common/get-attestation){target=\_blank} must be delivered to the destination chain. - -This attestation delivery may be difficult or impossible in some contexts. For example, in a browser context, the user doesn't wish to wait for finality to deliver the attestation. To address this difficulty, the Wormhole CCTP relayer may be used either with the [Wormhole Connect Widget](/docs/build/transfers/connect/overview/){target=\_blank} or more directly with the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank}. - -The Wormhole CCTP Relayer charges a fee to deliver the attestation and complete the transfer. - -| Chain | Fee | -|:---------------:|:---------------:| -| Ethereum | 1.0 USDC | -| Everything else | 0.1 USDC | - - + ```bash + touch src/scripts/native-transfer.ts + ``` -## Native Gas Drop Off +2. Open the `native-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files -Another advantage of using the automatic relaying feature is the opportunity to transfer some native gas to the receiver on the destination chain. This feature is referred to as _native gas drop off_. + ```typescript + Chain, + Network, + Wormhole, + amount, + wormhole, + TokenId, + TokenTransfer, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; + ``` -The ability to perform native gas drop off addresses the common issue where a user may hold a balance of USDC but has no native gas to perform subsequent transactions. +3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support - ---- END CONTENT --- + ```typescript + const wh = await wormhole('Testnet', [evm, solana, sui]); + ``` -Doc-Content: https://wormhole.com/docs/learn/transfers/ ---- BEGIN CONTENT --- ---- -title: Multichain Transfers -description: This section introduces the core messaging protocols that power seamless multichain communication and asset transfer within the Wormhole ecosystem. -categories: Transfer ---- +4. **Set up source and destination chains** - specify the source chain (Sui) and the destination chain (Solana) using the `getChain` method. This allows us to define where to send the native tokens and where to receive them -# Multichain Transfers + ```typescript + const rcvChain = wh.getChain('Solana'); + ``` -These sections include information about Wormhole's transfer products to help you learn how they work and determine the best transfer product to fit your needs. +5. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains -Use the following links to jump directly to each Wormhole transfer product information page or continue for a product comparison: + ```typescript + const destination = await getSigner(rcvChain); + ``` -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/) - a mechanism to transfer native tokens multichain seamlessly without converting to a wrapped asset -- [**Settlement**](/docs/learn/transfers/settlement/) - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods -- [**Token Bridge**](/docs/learn/transfers/token-bridge/) - a bridging solution that uses a lock and mint mechanism +6. **Define the token to transfer** - specify the native token on the source chain (Sui in this example) by creating a `TokenId` object -## Compare Transfer Products + ```typescript + + ``` -A few key comparisons can help you readily differentiate between Wormhole transfer product offerings. Use the following sections to help compare and select products: +7. **Define the transfer amount** - the amount of native tokens to transfer is specified. In this case, we're transferring 1 unit -### NTT vs. Token Bridge + ```typescript + + ``` -Understand the key differences between Native Token Transfers (NTT) and Token Bridge to determine which solution best fits your needs. +8. **Set transfer mode** - specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself -- Native Token Transfers (NTT) move tokens in their original form without wrapping them, ensuring compatibility with on-chain applications but requiring custom contracts on both the source and destination chains -- Token Bridge locks tokens on the source chain and mints wrapped versions on the destination chain. This method does not require changes to existing token contracts and supports additional message payloads for more complex use cases + ```typescript + + ``` -
+ !!! note + Automatic transfers are only supported for EVM chains. For non-EVM chains like Solana and Sui, you must manually handle the attestation and finalization steps. + +9. **Define decimals** - fetch the number of decimals for the token on the source chain (Sui) using the `getTokenDecimals` function -| Supports | NTT | Token Bridge | -|---------------------------|--------------------|--------------------| -| Message Payload | :white_check_mark: | :white_check_mark: | -| Wrapped Assets | :x: | :white_check_mark: | -| Native Assets | :white_check_mark: | :x: | -| Contract-Free Development | :x: | :white_check_mark: | -| User-Owned Contracts | :white_check_mark: | :x: | + ```typescript + + ``` -
+10. **Perform the token transfer and exit the process** - initiate the transfer by calling the `tokenTransfer` function, which we’ll define in the next step. This function takes an object containing all required details for executing the transfer, including the `source` and `destination` chains, `token`, `mode`, and transfer `amount` -In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: + ```typescript + token, + amount: amount.units(amount.parse(amt, decimals)), + source, + destination, + automatic, + }); + ``` -
+ Finally, we use `process.exit(0);` to close the script once the transfer completes + ```typescript + })(); + ``` -### Settlement +### Token Transfer Logic -Settlement enables fast and efficient multichain transfers by optimizing liquidity without relying on traditional bridging methods. Unlike NTT, which moves native assets directly between chains, and Token Bridge, which locks tokens and mints wrapped versions, Settlement uses intent-based execution. Users specify the desired transfer outcome, and solvers compete to fulfill it most efficiently. +This section defines the `tokenTransfer` function, which manages the core steps for cross-chain transfer execution. This function will handle initiating the transfer on the source chain, retrieving the attestation, and completing the transfer on the destination chain. -By leveraging a decentralized solver network, Settlement ensures efficient cross-chain liquidity without locking assets or requiring asset wrapping, providing a seamless and capital-efficient solution for multichain transactions. +#### Defining the Token Transfer Function -## Additional Resources +The `tokenTransfer` function initiates and manages the transfer process, handling all necessary steps to move tokens across chains with the Wormhole SDK. This function uses types from the SDK and our `helpers.ts` file to ensure chain compatibility. -
+```typescript +wh: Wormhole, + route: { + token: TokenId; + amount: bigint; + source: SignerStuff; + destination: SignerStuff; + automatic: boolean; + payload?: Uint8Array; + } +) { + // Token Transfer Logic +import { + Chain, + Network, + Wormhole, + amount, + wormhole, + TokenId, + TokenTransfer, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; -- :octicons-tools-16:{ .lg .middle } **Product Comparison** +(async function () { + const wh = await wormhole('Testnet', [evm, solana, sui]); - --- + // Set up source and destination chains + const sendChain = wh.getChain('Sui'); + const rcvChain = wh.getChain('Solana'); - Compare Wormhole's multichain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. + // Get signer from local key but anything that implements + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); - [:custom-arrow: Compare Products](/docs/build/start-building/products/#transfer-products) + // Shortcut to allow transferring native gas token + const token = Wormhole.tokenId(sendChain.chain, 'native'); -- :octicons-book-16:{ .lg .middle } **Use Cases** + // Define the amount of tokens to transfer + const amt = '1'; - --- + // Set automatic transfer to false for manual transfer + const automatic = false; - Explore Wormhole's use cases, from multichain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. + // Used to normalize the amount to account for the tokens decimals + const decimals = await getTokenDecimals(wh, token, sendChain); - [:custom-arrow: Discover Use Cases](/docs/build/start-building/use-cases/) + // Perform the token transfer if no recovery transaction ID is provided + const xfer = await tokenTransfer(wh, { + token, + amount: amount.units(amount.parse(amt, decimals)), + source, + destination, + automatic, + }); + process.exit(0); +})(); -
---- END CONTENT --- +async function tokenTransfer( + wh: Wormhole, + route: { + token: TokenId; + amount: bigint; + source: SignerStuff; + destination: SignerStuff; + automatic: boolean; + payload?: Uint8Array; + } +) { + // Token Transfer Logic + // Create a TokenTransfer object to track the state of the transfer over time + const xfer = await wh.tokenTransfer( + route.token, + route.amount, + route.source.address, + route.destination.address, + route.automatic ?? false, + route.payload + ); -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/architecture/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Architecture -description: Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. -categories: NTT, Transfer ---- + const quote = await TokenTransfer.quoteTransfer( + wh, + route.source.chain, + route.destination.chain, + xfer.transfer + ); -## Introduction + if (xfer.transfer.automatic && quote.destinationToken.amount < 0) + throw 'The amount requested is too low to cover the fee and any native gas requested.'; -The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. + // Submit the transactions to the source chain, passing a signer to sign any txns + console.log('Starting transfer'); + const srcTxids = await xfer.initiateTransfer(route.source.signer); + console.log(`Source Trasaction ID: ${srcTxids[0]}`); + console.log(`Wormhole Trasaction ID: ${srcTxids[1] ?? srcTxids[0]}`); -For the technical implementations of the functions, refer to the [Managers and Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/){target=\_blank} page. + // Wait for the VAA to be signed and ready (not required for auto transfer) + console.log('Getting Attestation'); + await xfer.fetchAttestation(60_000); -## System Components + // Redeem the VAA on the dest chain + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(route.destination.signer); + console.log(`Completed Transfer: `, destTxids); +} + +``` -The NTT framework is composed of managers, which oversee the transfer process, and transceivers, which handle cross-chain messaging, ensuring smooth and reliable token transfers. +#### Steps to Transfer Tokens -### Managers +The `tokenTransfer` function consists of several key steps to facilitate the cross-chain transfer. Let’s break down each step: -_Managers_ are responsible for handling the flow of token transfers between different blockchains and ensuring that tokens are locked or burned on the source chain before being minted or unlocked on the destination chain. The main tasks of managers include rate-limiting transactions, verifying message authenticity (message attestation), and managing the interaction between multiple transceivers, who are responsible for cross-chain communications. +1. **Initialize the transfer object** - the `tokenTransfer` function begins by creating a `TokenTransfer` object, `xfer`, which tracks the state of the transfer process and provides access to relevant methods for each transfer step -Each manager is assigned to a specific token but can operate across multiple chains. Their key responsibility is to ensure that tokens are securely locked or burned on the source chain before being minted or unlocked on the destination chain. This provides the integrity of token transfers and prevents double-spending. + ```typescript + route.token, + route.amount, + route.source.address, + route.destination.address, + route.automatic ?? false, + route.payload + ); + ``` -A manager is responsible for: +2. **Estimate transfer fees and validate amount** - we obtain a fee quote for the transfer before proceeding. This step is significant in automatic mode (`automatic = true`), where the quote will include additional fees for relaying -- **Handling token transfer flow** - upon a transfer request, `NttManager` either locks or burns tokens depending on the configuration, emits a `TransferSent` event, and ensures tokens can’t be accessed on the source chain before leasing them on the destination chain. This process safeguards against double-spending and maintains a secure transfer -- **Rate-limiting** - the `NttManager` contract includes rate-limiting functionality to prevent overloading the network or flooding the target chain. The `NttManager` applies rate limits to manage transfer flow and prevent network congestion. Limits apply to both outgoing and incoming transfers - - **Outbound** - transfers exceeding the outbound limit are queued (if `shouldQueue` is true) or reverted - - **Inbound** - similar limits apply on the destination chain, delaying transfers if capacity is exceeded + ```typescript + wh, + route.source.chain, + route.destination.chain, + xfer.transfer + ); - Rate limit duration and queuing are customizable per chain, and events notify users when transfers hit the limit + if (xfer.transfer.automatic && quote.destinationToken.amount < 0) + throw 'The amount requested is too low to cover the fee and any native gas requested.'; + ``` -- **Message authenticity verification** - the `NttManager` ensures transfer security by verifying message authenticity through multiple attestations from transceivers. For each transfer, a threshold number of attestation signatures must be gathered from transceivers. Once verified, `NttManager` releases tokens on the destination chain, ensuring only authenticated transfers are processed -- **Interaction with transceivers** - `NttManager` collaborates with transceivers, forwarding transfer messages between chains and handling message verification. Transceivers route messages with transfer details to the destination chain, coordinating with `NttManager` to verify that tokens are locked or burned before releasing them on the other side. Transceivers can be customized to work with different security protocols, adding flexibility +3. **Submit the transaction to the source chain** - initiate the transfer on the source chain by submitting the transaction using `route.source.signer`, starting the token transfer process -### Transceivers + ```typescript + console.log(`Source Trasaction ID: ${srcTxids[0]}`); + ``` -_Transceivers_ facilitate cross-chain token transfers by ensuring the accurate transmission of messages between different blockchains. They work in conjunction with managers to route token transfers from the source chain to the recipient chain. Their primary function is to ensure that messages regarding the transfer process are delivered correctly, and that tokens are safely transferred across chains. + - **`srcTxids`** - the resulting transaction IDs are printed to the console. These IDs can be used to track the transfer’s progress on the source chain and [Wormhole network](https://wormholescan.io/#/?network=Testnet){target=\_blank} -While transceivers operate closely with Wormhole's ecosystem, they can also be configured independently of Wormhole's core system, allowing for flexibility. This adaptability allows them to be integrated with various verification backends to accommodate different security needs or platform-specific requirements. + ???- note "How Cross-Chain Transfers Work in the Background" + When `xfer.initiateTransfer(route.source.signer)` is called, it initiates the transfer on the source chain. Here’s what happens in the background: -Transceivers are entrusted with several responsibilities: + - **Token lock or burn** - tokens are either locked in a smart contract or burned on the source chain, representing the transfer amount + - **VAA creation** - Wormhole’s network of Guardians generates a Verifiable Action Approval (VAA)—a signed proof of the transaction, which ensures it’s recognized across chains + - **Tracking the transfer** - the returned transaction IDs allow you to track the transfer's progress both on the source chain and within Wormhole’s network + - **Redemption on destination** - once detected, the VAA is used to release or mint the corresponding token amount on the destination chain, completing the transfer -- **Message transmission** - transceivers handle the routing of transfer messages between chains. When a transfer is initiated, the transceiver sends the message (including transfer details like recipient and amount) to the destination chain’s manager for verification and processing -- **Manager coordination** - transceivers work with managers to ensure tokens are locked or burned on the source chain before issuance on the destination chain, reinforcing the security of each transfer -- **Custom verification support** - transceivers can integrate with custom verification backends, allowing flexibility to adapt to different security protocols or chain requirements. This customization enables protocols to use different attestation standards as needed + This process ensures a secure and verifiable transfer across chains, from locking tokens on the source chain to redeeming them on the destination chain. -How it works: +4. **Wait for the attestation** - retrieve the Wormhole attestation (VAA), which serves as cryptographic proof of the transfer. In manual mode, you must wait for the VAA before redeeming the transfer on the destination chain -1. The transceiver receives instructions from the manager to send messages across chains -2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred -3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain + ```typescript + + ``` -![NTT architecture diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-1.webp) +5. **Complete the transfer on the destination chain** - redeem the VAA on the destination chain to finalize the transfer -!!! note - [Learn more](/docs/learn/transfers/native-token-transfers/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. + ```typescript + console.log(`Completed Transfer: `, destTxids); + ``` -#### Custom Transceivers - -The NTT framework supports advanced features such as custom transceivers for specialized message verification, enhancing security and adaptability. The architecture includes detailed processes for initiating transfers, managing rate limits, and finalizing token operations, with specific instructions and events outlined for EVM-compatible chains and Solana. - -NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. - -![Custom Attestation with NTT diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-2.webp) +??? code "Complete script" + ```typescript + import { + Chain, + Network, + Wormhole, + amount, + wormhole, + TokenId, + TokenTransfer, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; -The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. +(async function () { + const wh = await wormhole('Testnet', [evm, solana, sui]); -For more details, to collaborate, or to see examples of custom transceivers, [contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors. + // Set up source and destination chains + const sendChain = wh.getChain('Sui'); + const rcvChain = wh.getChain('Solana'); -## Lifecycle of a Message + // Get signer from local key but anything that implements + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -The lifecycle of a message in the Wormhole ecosystem for Native Token Transfers (NTT) involves multiple steps to ensure secure and accurate cross-chain token transfers. This lifecycle can vary depending on the blockchain being used, and the following explanations focus on the EVM and Solana implementations. The key stages include initiating the transfer, handling rate limits, sending and receiving messages, and finally, minting or unlocking tokens on the destination chain. + // Shortcut to allow transferring native gas token + const token = Wormhole.tokenId(sendChain.chain, 'native'); -### Transfer + // Define the amount of tokens to transfer + const amt = '1'; -The process begins when a client initiates a transfer. For EVM, this is done using the `transfer` function, whereas in Solana, the client uses either the `transfer_lock` or `transfer_burn` instruction, depending on whether the program is in locking or burning mode. The client specifies the transfer amount, recipient chain ID, recipient address, and a flag (`should_queue` on both EVM and Solana) to decide whether the transfer should be queued if it hits the rate limit. + // Set automatic transfer to false for manual transfer + const automatic = false; -In both cases: + // Used to normalize the amount to account for the tokens decimals + const decimals = await getTokenDecimals(wh, token, sendChain); -- If the source chain is in locking mode, the tokens are locked on the source chain to be unlocked on the destination chain -- If the source chain is in burning mode, the tokens are burned on the source chain, and new tokens are minted on the destination chain + // Perform the token transfer if no recovery transaction ID is provided + const xfer = await tokenTransfer(wh, { + token, + amount: amount.units(amount.parse(amt, decimals)), + source, + destination, + automatic, + }); -Once initiated, an event (such as `TransferSent` on EVM or a corresponding log on Solana) is emitted to signal that the transfer process has started. + process.exit(0); +})(); -### Rate Limit +async function tokenTransfer( + wh: Wormhole, + route: { + token: TokenId; + amount: bigint; + source: SignerStuff; + destination: SignerStuff; + automatic: boolean; + payload?: Uint8Array; + } +) { + // Token Transfer Logic + // Create a TokenTransfer object to track the state of the transfer over time + const xfer = await wh.tokenTransfer( + route.token, + route.amount, + route.source.address, + route.destination.address, + route.automatic ?? false, + route.payload + ); -Both EVM and Solana implement rate-limiting for transfers to prevent abuse or network overload. Rate limits apply to both the source and destination chains. If transfers exceed the current capacity, depending on whether the `shouldQueue` flag is set to true, they can be queued. + const quote = await TokenTransfer.quoteTransfer( + wh, + route.source.chain, + route.destination.chain, + xfer.transfer + ); -- On EVM, the transfer is added to an outbound queue if it hits the rate limit, with a delay corresponding to the configured rate limit duration. If `shouldQueue` is set to false, the transfer is reverted with an error -- On Solana, the transfer is added to an **Outbox** via the `insert_into_outbox method`, and if the rate limit is hit, the transfer is queued with a `release_timestamp`. If `shouldQueue` is false, the transfer is reverted with a `TransferExceedsRateLimit` error + if (xfer.transfer.automatic && quote.destinationToken.amount < 0) + throw 'The amount requested is too low to cover the fee and any native gas requested.'; -Both chains emit events or logs when transfers are rate-limited or queued. + // Submit the transactions to the source chain, passing a signer to sign any txns + console.log('Starting transfer'); + const srcTxids = await xfer.initiateTransfer(route.source.signer); + console.log(`Source Trasaction ID: ${srcTxids[0]}`); + console.log(`Wormhole Trasaction ID: ${srcTxids[1] ?? srcTxids[0]}`); -### Send + // Wait for the VAA to be signed and ready (not required for auto transfer) + console.log('Getting Attestation'); + await xfer.fetchAttestation(60_000); -After being forwarded to the Transceiver, the message is transmitted across the chain. Transceivers are responsible for delivering the message containing the token transfer details. Depending on the Transceiver's implementation, messages may be routed through different systems, such as Wormhole relayers or other custom relaying solutions. Once the message is transmitted, an event is emitted to signal successful transmission. + // Redeem the VAA on the dest chain + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(route.destination.signer); + console.log(`Completed Transfer: `, destTxids); +} + + ``` -- In EVM, the message is sent using the `sendMessage` function, which handles the transmission based on the Transceiver's implementation. The Transceiver may use Wormhole relayers or custom relaying solutions to forward the message -- In Solana, the transfer message is placed in an Outbox and released via the `release_outbound` instruction. The Solana transceiver, such as the Wormhole Transceiver, may send the message using the `post_message` instruction, which Wormhole Guardians observe for verification +### Run the Native Token Transfer -In both cases, an event or log (e.g., `SendTransceiverMessage` on EVM or a similar log on Solana) is emitted to signal that the message has been transmitted. +Now that you’ve set up the project and defined the transfer logic, you can execute the script to transfer native tokens from the Sui chain to Solana. You can use `tsx` to run the TypeScript file directly: -### Receive +```bash +npx tsx src/scripts/native-transfer.ts +``` -Upon receiving the message on the destination chain, an off-chain relayer forwards the message to the destination Transceiver for verification. +This initiates the native token transfer from the source chain (Sui) and completes it on the destination chain (Solana). -- In EVM, the message is received by the `NttManager` on the destination chain, which verifies the message's authenticity. Depending on the M of N threshold set for the attestation process, the message may require attestations from multiple transceivers -- In Solana, the message is received via the `receive_message` instruction in the Wormhole Transceiver program. The message is verified and stored in a `VerifiedTransceiverMessage` account, after which it is placed in an Inbox for further processing +You can monitor the status of the transaction on the [Wormhole explorer](https://wormholescan.io/#/?network=Testnet){target=\_blank}. -In both chains, replay protection mechanisms ensure that a message cannot be executed more than once. Events or logs are emitted (e.g., `ReceivedMessage` on EVM or `ReceiveMessage` on Solana) to notify that the message has been successfully received. +## Resources -### Mint or Unlock +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in [Wormhole's demo GitHub repository](https://github.com/wormhole-foundation/demo-basic-ts-sdk/){target=\_blank}. The repository includes all the example scripts and configurations needed to perform native token cross-chain transfers, including manual, automatic, and partial transfers using the Wormhole SDK. -Finally, after the message is verified and attested to, the tokens can be either minted (if they were burned on the source chain) or unlocked (if they were locked). The tokens are then transferred to the recipient on the destination chain, completing the cross-chain token transfer process. +## Conclusion -- On EVM, tokens are either minted (if burned on the source chain) or unlocked (if locked on the source chain). The `TransferRedeemed` event signals that the tokens have been successfully transferred -- On Solana, the tokens are unlocked or minted depending on whether the program is in locking or burning mode. The `release_inbound_unlock` or `release_inbound_mint` instruction is used to complete the transfer, and a corresponding log is produced +You've successfully built a cross-chain token transfer application using Wormhole's TypeScript SDK and the Token Bridge method. This guide took you through the setup, configuration, and transfer logic required to move native tokens across non-EVM chains like Sui and Solana. -In both cases, once the tokens have been released, the transfer process is complete, and the recipient receives the tokens. Events are emitted to indicate that the transfer has been fully redeemed. +The same transfer logic will apply if you’d like to extend this application to different chain combinations, including EVM-compatible chains. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/deployment/ +Doc-Content: https://wormhole.com/docs/protocol/architecture/ --- BEGIN CONTENT --- --- -title: Native Token Transfers - Deployment Models -description: Explore Wormhole's Native Token Transfers deployment models——hub-and-spoke, burn-and-mint——for seamless cross-chain token transfers. -categories: NTT, Transfer +title: Architecture +description: Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +categories: Basics --- -# Deployment Models - -The Wormhole framework offers two deployment models, each catering to different token management needs: the hub-and-spoke model and the burn-and-mint model. These models provide flexible solutions for both existing token deployments and new projects looking to enable secure and seamless multichain token transfers. - -## Hub-and-Spoke +# Architecture -The hub-and-spoke model involves locking tokens on a central hub chain and minting them on destination spoke chains. This model maintains the total supply on the hub chain and is backward-compatible with any existing token deployment. +## Overview -This model is ideal for existing token deployments that don't want to alter existing token contracts. It maintains the canonical balance on a hub chain while allowing for secure native deployment to new blockchains. +Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -- **Hub chain** - tokens are locked when initiating a transfer -- **Spoke chains** - Equivalent tokens are minted on the destination chain +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) -When transferring tokens back to the original hub chain, the tokens on the source spoke chain are burned, and the previously locked tokens on the hub chain are unlocked. However, when transferring tokens directly between spoke chains, the tokens are burned on the source spoke chain and minted on the destination spoke chain. +The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -## Burn-and-Mint +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} +3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain +4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. -The burn-and-mint model involves burning tokens on the source chain and minting them on the destination chain. This results in a simplified multichain transfer process that distributes the total supply across multiple chains and produces a native multichain token. + The flow from the relayer to the target chain involves an entry point contract, which could vary based on the use case: -This model best suits new token deployments or projects willing to upgrade existing contracts. + - In some applications, the target contract acts as the entry point and performs verification via the Core Contract + - In products like the Token Bridge, the Token Bridge contract itself interacts with the Core Contract -- **Source chain** - tokens are burned when initiating a transfer -- **Destination chain** - equivalent tokens are minted on the destination chain ---- END CONTENT --- +## On-Chain Components -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/ ---- BEGIN CONTENT --- ---- -title: A Quick Look at Native Token Transfers -description: This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. -categories: NTT, Transfer ---- +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract -# Native Token Transfers +## Off-Chain Components -## Get Started +- **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain + - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract + - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers -This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. +## Next Steps
-- :octicons-question-16:{ .lg .middle } **Overview** - - --- - - Dive into an introduction to NTT and discover what NTT is, what its key features are, and the available integration paths. - - [:custom-arrow: Learn more about NTT](/docs/learn/transfers/native-token-transfers/overview/) - -- :octicons-question-16:{ .lg .middle } **Architecture** +- :octicons-book-16:{ .lg .middle } **Core Contracts** --- - Explore NTT's architecture to understand its core components and how they work together to manage cross-chain communication. + Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - [:custom-arrow: Discover how NTT works](/docs/learn/transfers/native-token-transfers/architecture/) + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) -- :octicons-book-16:{ .lg .middle } **Deployment Models** +- :octicons-tools-16:{ .lg .middle } **Core Messaging** --- - The NTT framework offers two deployment models for different token management needs: the hub-and-spoke and burn-and-mint models. - - [:custom-arrow: Check out the deployment models](/docs/learn/transfers/native-token-transfers/deployment/) - -- :octicons-shield-lock-16:{ .lg .middle } **Security** + Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. - --- + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/) - Explore NTT's security measures, including the Global Accountant and governance strategies for seamless token safety. +
+--- END CONTENT --- - [:custom-arrow: Review the security measures](/docs/learn/transfers/native-token-transfers/security/) +Doc-Content: https://wormhole.com/docs/protocol/ecosystem/ +--- BEGIN CONTENT --- +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- -
+# The Wormhole Ecosystem -## Next Steps +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. -Ready to dive in and start building? Check out the following resources to begin the deployment process and make the most of your deployment. +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. -
+This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. -- :octicons-rocket-16:{ .lg .middle } **Deploy NTT** +## Ecosystem Overview - --- +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: - Explore detailed guides that walk you through the entire deployment process, from installing the NTT CLI to deploying NTT across supported chains. +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. - [:custom-arrow: Deploy now using the NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/) +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) -- :octicons-checklist-16:{ .lg .middle } **Post Deployment Recommendations** +## Bringing It All Together: Interoperability in Action - --- +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. - Already deployed your NTT project? Check out these post deployment recommendations and integration demos to get the most out of your deployment. +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. - [:custom-arrow: Get the most of out your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/) +## Next Steps -
+Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/overview/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure-guides/run-relayer/ --- BEGIN CONTENT --- --- -title: Native Token Transfers Overview -description: Explore Wormhole's Native Token Transfers for flexible cross-chain transfers with full control over token behavior, security, and integration features. -categories: NTT, Transfer +title: Run a Relayer +description: Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +categories: Relayers --- -# Native Token Transfers - -!!!tip "Looking to deploy NTT?" - If you're ready to deploy NTT or access the CLI, follow the detailed [NTT Deployment Section](/docs/build/transfers/native-token-transfers/deployment-process/){target=\_blank}. - - - For deployment steps on EVM, visit the [Deploy to EVM page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} - - For deployment steps on Solana, visit the [Deploy to Solana page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/){target=\_blank} +# Run a Custom Relayer ## Introduction -Wormhole's Native Token Transfers (NTT) is an open source, flexible, and composable framework for transferring tokens across blockchains. By eliminating wrapped assets, NTT preserves each token’s native properties across chains, letting you maintain complete control over metadata, ownership, upgrade authority, and other custom features. - -The framework offers two modes of operation for existing token deployments. In locking mode, the original token supply is preserved on a single chain. In contrast, the burning mode enables the deployment of multichain tokens, distributing the supply across various chains. - -## Key Features - -Wormhole's Native Token Transfers (NTT) framework offers a comprehensive and flexible solution for seamless token transfers across blockchains. Below are some of the key features that make this framework stand out: - -- **No wrapped tokens** – tokens remain native on every chain where NTT is deployed. All token properties and metadata remain consistent, avoiding any confusion or overhead introduced by wrapped tokens -- **Unified user experience** - tokens retain their properties on each chain, remaining completely fungible and ensuring a consistent user experience -- **No liquidity pools** - transfer tokens without the need for liquidity pools, avoiding fees, slippage, and MEV risk -- **Integrator flexibility** - retained ownership, upgrade authority, and complete customizability over token contracts -- **Advanced rate limiting** - inbound and outbound rate limits are configurable per chain and over arbitrary periods, preventing abuse while managing network congestion and allowing for controlled deployments to new chains -- **Global Accountant** - ensures accounting integrity across chains by checking that the number of tokens burned and transferred out of a chain never exceeds the number of tokens minted -- **Access control** - to prevent unauthorized calls to administrative functions, protocols can choose to assign specific functions, such as the Pauser role, to a separate address from the owner -- **Maximum composability** - open source and extensible for widespread adoption and integration with other protocols -- **Custom attestation** - optionally add external verifiers and configure custom message attestation thresholds +Relayers play a crucial role in cross-chain communication, ensuring that messages are transferred seamlessly between different blockchains. While Wormhole relayers provide a reliable way to handle these transfers, they might not always meet every application's unique requirements. -## Integration Paths +Custom relayers address these limitations by offering tailored solutions that cater to the distinct needs of your application. Developing a custom relayer gives you complete control over message processing, delivery mechanisms, and integration with existing systems. This customization allows for optimized performance and the ability to implement specific features that Wormhole-deployed relayers might not support. -Integrators looking to deploy their token to connected chains can use the NTT framework or the Token Bridge. Both options carry a distinct integration path and feature set depending on your requirements, as outlined in the following sections. +A custom relayer might be as simple as an in-browser process that polls the API for the availability of a VAA after submitting a transaction and delivers it to the target chain. It might also be implemented with a Spy coupled with some daemon listening for VAAs from a relevant chain ID and emitter, then taking action when one is observed. -### Native Token Transfers Framework +This guide teaches you how to set up and configure a custom relayer for efficient message handling. You'll start by understanding how to uniquely identify a VAA using its emitter address, sequence ID, and chain ID. Then, you'll explore the Relayer Engine, a package that provides a framework for building custom relayers, and learn how to fetch and handle VAAs using the Wormhole SDK. -The Native Token Transfers Framework is highly customizable and ideal for applications such as a DeFi governance token deployed across multiple chains, which seeks to achieve fungible multichain liquidity and direct integration into governance processes. +## Get Started with a Custom Relayer -- **Mechanism** - can entirely utilize a burn-and-mint mechanism or can be paired for a hub-and-spoke model -- **Security** - fully configurable rate limiting, pausing, access control, and threshold attestations. Integrated with the Global Accountant -- **Contract ownership** - retain ownership and upgrade authority of token contracts on each chain -- **Token contracts** - native contracts owned by your protocol governance -- **Integration** - streamlined, customizable framework allows for more sophisticated and bespoke deployments +To start building a custom relayer, it's essential to grasp the components you'll be managing as part of your relaying service. Your relayer must be capable of retrieving and delivering VAAs. -The following example projects demonstrate the use of the Wormhole NTT framework through Wormhole Connect and the TypeScript SDK: +
+ ![Custom relayer](/docs/images/protocol/infrastructure-guides/run-relayer/relayer-1.webp) +
The off-chain components outlined in blue must be implemented.
+
-- [NTT Connect](https://github.com/wormhole-foundation/demo-ntt-connect){target=\_blank} -- [NTT TS SDK](https://github.com/wormhole-foundation/demo-ntt-ts-sdk){target=\_blank} +### How to Uniquely Identify a VAA -### Token Bridge +Regardless of the environment, to get the VAA you intend to relay, you need: -The Token Bridge offers a secure, low-effort integration suitable for applications like a Web3 game that wants to make its token tradable across multiple chains. +- The `emitter` address +- The `sequence` ID of the message you're interested in +- The `chainId` for the chain that emitted the message -- **Mechanism** - solely utilizes a lock and mint model. Unlike NTT, the Token Bridge issues a wrapped asset on the destination chain, rather than preserving the original token contract -- **Security** - preconfigured rate limiting and integrated Global Accountant -- **Contract ownership** - Token Bridge contracts are upgradeable via [Wormhole Governance](/docs/learn/security/){target=\_blank} -- **Token contracts** - wrapped asset contract owned by the Wormhole Token Bridge contract, upgradeable via a 13/19 Guardian governance process -- **Integration** - straightforward and permissionless method to deploy on multiple chains +With these three components, you're able to uniquely identify a VAA and process it. -!!! note - [Learn more](/docs/learn/infrastructure/vaas/){target=\_blank} about the core messaging primitives in the Wormhole network. +## Use the Relayer Engine -## Supported Token Standards +The [`relayer-engine`](https://github.com/wormhole-foundation/relayer-engine){target=\_blank} is a package that provides the structure and a starting point for a custom relayer. -Native Token Transfers (NTT) in Wormhole primarily support **ERC-20 tokens**, the most widely used standard for fungible tokens on the Ethereum network and other EVM-compatible blockchains. The NttManager contract leverages the IERC20 interface and SafeERC20 utility from OpenZeppelin to ensure secure and efficient token transfers. Additionally, it supports ERC-20 Burnable tokens, allowing tokens to be burned on the source chain when needed for cross-chain transfers. At this time, NTT focuses on ERC-20 tokens, and other token standards, such as ERC-721 (non-fungible tokens) or ERC-1155 (multi-token standard), are not natively supported. ---- END CONTENT --- +With the Relayer Engine, a developer can write specific logic for filtering to receive only the messages they care about. -Doc-Content: https://wormhole.com/docs/learn/transfers/native-token-transfers/security/ ---- BEGIN CONTENT --- ---- -title: Native Token Transfers Security -description: Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. -categories: NTT, Transfer ---- +Once a Wormhole message is received, the developer may apply additional logic to parse custom payloads or submit the Verifiable Action Approvals (VAA) to one or many destination chains. -# Security +To use the Relayer Engine, a developer may specify how to relay Wormhole messages for their app using an idiomatic Express/Koa middleware-inspired API, then let the library handle all the details. -## Global Accountant +### Install the Relayer Engine -The Global Accountant is a defense-in-depth security feature that checks the integrity of every token transfer. It ensures that chain balances remain isolated and more tokens cannot be burned and transferred out of a chain than were ever minted. +First, install the `relayer-engine` package with your favorite package manager: -This feature ensures native asset fungibility remains in 1:1 parity. At no time will assets coming from a spoke chain exceed the number of native assets sent to that spoke chain. The Guardians, with their role in enforcing accounting transparency, provide a reassuring layer of security, attesting to a Native Token Transfer (NTT) only if it passes integrity checks. +```bash +npm i @wormhole-foundation/relayer-engine +``` -[Contact](https://discord.com/invite/wormholecrypto){target=\_blank} Wormhole contributors if you are interested in configuring the Global Accountant for your multichain deployment. +### Get Started with the Relayer Engine -## Governance and Upgradeability +In the following example, you'll: -Integrators should implement governance mechanisms to manage the addition and removal of transceivers and to upgrade contracts using proxy patterns, as demonstrated in the upgrade functions in the `NttManager` contracts. These processes can also set thresholds and rules for attestation and message approval. +1. Set up a `StandardRelayerApp`, passing configuration options for our relayer +2. Add a filter to capture only those messages our app cares about, with a callback to do _something_ with the VAA once received +3. Start the relayer app -The registry component of the NTT system is crucial for maintaining a trusted list of transceivers and managing their status. Governance processes for the following actions can be submitted directly to the corresponding contract on-chain, whether it is one or multiple of the bridging contracts or one of the token contracts: +```typescript +import { + Environment, + StandardRelayerApp, + StandardRelayerContext, +} from '@wormhole-foundation/relayer-engine'; +import { CHAIN_ID_SOLANA } from '@certusone/wormhole-sdk'; -- Adding or removing a transceiver address from the registry -- Setting the token contract address on a bridging contract -- Setting the Wormhole Core Contract address on a bridging contract -- Setting the registered bridging contract address on the token contract - -This governance model ensures that the system remains secure while being adaptable to new requirements in any environment where it is deployed. ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/architecture/ ---- BEGIN CONTENT --- ---- -title: Settlement Protocol Architecture -description: Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. -categories: Settlement, Transfer ---- - -# Settlement Protocol Architecture - -## Introduction - -This page describes the high-level mechanics of the underlying native swap protocols in the Wormhole SDK. While built on Wormhole messaging, each protocol uses a novel architecture with unique price discovery, scalability, and latency tradeoffs. These designs enable redundancy to handle highly asymmetric flows and sharp volume changes. These sections will cover the following: - -- **Wormhole Liquidity Layer** - a cross-chain transfer protocol that utilizes Solana as the central orchestration layer for cross-chain intents, allowing solvers to deploy liquidity from a single Solana-based hub rather than distributing it across each supported chain -- **Mayan Swift** - a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent -- **Mayan MCTP** - a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains - -## Wormhole Liquidity Layer - -Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster-than-finality transfers across the Wormhole ecosystem through a novel, Solana-based hub-and-spoke architecture. The hub-and-spoke model leverages interoperable token standards like Circle's CCTP (and Wormhole's NTT), allowing the solver to natively mint and burn assets between chains for intent fulfillment. This architecture allows solvers to facilitate cross-chain transfers by fronting assets on the destination chain and assuming the finality risk of the originating source chain transaction. - -Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. +(async function main() { + // Initialize relayer engine app and pass relevant config options + const app = new StandardRelayerApp( + Environment.TESTNET, + // Other app specific config options can be set here for things + // like retries, logger, or redis connection settings + { + name: 'ExampleRelayer', + } + ); -![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/learn/transfers/settlement/architecture/architecture-1.webp) + // Add a filter with a callback that will be invoked + // on finding a VAA that matches the filter + app.chain(CHAIN_ID_SOLANA).address( + // Emitter address on Solana + 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe', + // Callback function to invoke on new message + async (ctx, next) => { + const vaa = ctx.vaa; + const hash = ctx.sourceTxHash; + console.log( + `Got a VAA with sequence: ${vaa.sequence} from with txhash: ${hash}` + ); + } + ); -The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. + // Add and configure any other middleware here -### Solvers and Liquidity Fragmentation + // Start app. Blocks until unrecoverable error or process is stopped + await app.listen(); +})(); + +``` -Traditional intent-based protocols require solvers to distribute their capital across each supported chain in the network. This liquidity fragmentation leads to capital inefficiency and requires complex rebalancing to manage asymmetric flows between chains. As the number of chains increases, solvers face scalability challenges, which can result in market concentration, reducing competition and potentially impacting price discovery in intent execution. +The first meaningful line instantiates the `StandardRelayerApp`, a subclass of the `RelayerApp` with standard defaults. -Using a hub-and-spoke model, the Wormhole Liquidity Layer solves these challenges by consolidating solver liquidity on a single chain, Solana. This model eliminates the need for complex cross-chain rebalancing and simplifies solvers' infrastructure requirements. Solvers only need to consider the finality risk of the originating source chain transaction and the payload size when bidding on transfers. By concentrating liquidity on Solana, the protocol can handle large transfer volumes with a smaller capital base, enhancing capital efficiency and lowering barriers to entry for solvers. This approach promotes competition, improves overall market efficiency, and ultimately benefits users with better prices while still preserving the speed of transactions. +```typescript +export class StandardRelayerApp< + ContextT extends StandardRelayerContext = StandardRelayerContext, +> extends RelayerApp { + // ... + constructor(env: Environment, opts: StandardRelayerAppOpts) { +``` -### Enable Unified Liquidity +The only field you pass in the `StandardRelayerAppOpts` is the name to help identify log messages and reserve a namespace in Redis. -The novel hub-and-spoke liquidity architecture relies on interoperable token standards that enable cross-chain token fungibility, such as Circle's Cross-Chain Transfer Protocol (CCTP) and Wormhole's Native Token Transfers (NTT). These protocols allow assets to move seamlessly between chains, making unified liquidity possible. On the liquidity hub (Solana), solvers concentrate their liquidity in NTT or CCTP-supported assets, such as USDC. These assets act as the shuttle between chains but may not necessarily be the user's original or final asset. +??? code "`StandardRelayerAppOpts`" -After the Solana auction concludes, the appropriate instructions are called on the CCTP or NTT contract, initiating the transfer from Solana to the destination chain by burning/locking the asset on Solana and sequentially minting on the destination chain. Solvers rebalance their inventory on Solana using these interoperable token standards as well. Once the originating source chain transaction reaches finality and arrives to Solana, the solver can redeem the NTT or CCTP message, minting the inventory for use once again. + Other options can be passed to the `StandardRelayerApp` constructor to configure the app further. -By leveraging interoperable token standards like NTT, this model of liquidity facilitation for cross-chain intents can arbitrarily scale to any chain or ecosystem while preserving fully unified liquidity. This removes the need for solver "buy-in" when expanding to new chains. Additionally, regardless of proven traction, new chains can access the same level of liquidity for cross-chain intent fulfillment from the first day of mainnet launch as long-standing ecosystems with clear evidence of adoption. This is often overlooked by solvers, who must aggressively prioritize high-flow chains due to high opportunity costs. The model also supports ecosystems without Centralized Exchange (CEX) enabled withdrawals. + ```typescript + wormholeRpcs?: string[]; // List of URLs from which to query missed VAAs +concurrency?: number; // How many concurrent requests to make for workflows +spyEndpoint?: string; // The hostname and port of our Spy +logger?: Logger; // A custom Logger +privateKeys?: Partial<{ [k in ChainId]: any[]; }>; // A set of keys that can be used to sign and send transactions +tokensByChain?: TokensByChain; // The token list we care about +workflows?: { retries: number; }; // How many times to retry a given workflow +providers?: ProvidersOpts; // Configuration for the default providers +fetchSourceTxhash?: boolean; // whether or not to get the original transaction ID/hash +// Redis config +redisClusterEndpoints?: ClusterNode[]; +redisCluster?: ClusterOptions; +redis?: RedisOptions; + ``` -### Protocol Flow: How It Works +The next meaningful line in the example adds a filter middleware component. This middleware will cause the relayer app to request a subscription from the Spy for any VAAs that match the criteria and invoke the callback with the VAA. -1. **Initiation** - users or protocols initiate a transfer via an interface or directly on-chain. They choose between a standard transfer (waiting for finality on the sending chain) or a fast transfer (triggering the auction process). For fast transfers, users or the protocol specify a maximum fee and an auction start deadline +If you'd like your program to subscribe to `multiple` chains and addresses, you can call the same method several times or use the `multiple` helper. - !!! Note - If an auction doesn't start within the set deadline, a standard transfer will proceed directly from the source to the destination chain. +```typescript +app.multiple( + { + [CHAIN_ID_SOLANA]: 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe', + [CHAIN_ID_ETH]: ['0xabc1230000000...', '0xdef456000...'], + }, + myCallback +); +``` -2. **Auction** - solvers monitor the Wormhole network for these fast transfer requests and initiate an auction on Solana by offering to fulfill the transfer at or below the user's maximum fee. To start the auction, the solver must transfer the requested funds plus a small security deposit to the Matching Engine contract -3. **Competition** - once initiated, other solvers can participate by submitting lower bids in a simple English auction, aiming to provide users with the best rate. If a new solver submits a better offer, the previous solver's funds and security deposit are returned, with the latest offer taking precedence atomically. This competition ensures that users receive the best possible transfer rate -4. **Fulfillment** - after the auction concludes, the winning solver must complete the transfer within a predefined grace period to earn their fee and reclaim their security deposit. Failure to do so may result in the security deposit being slashed, with the slashed amount compensating the user for delays. This mechanism incentivizes prompt execution. Upon successful completion, the Fast Transfer hub sends the USDC to the user's destination wallet, and the solver receives their security deposit and transfer fee -5. **Settlement** - once the source chain transaction reaches finality, the winning solver can use the finalized Wormhole message to settle the auction with the matching engine and rebalance. This allows the solver to retrieve the original transfer amount into their wallet +The last line in the simple example runs `await app.listen()`, which starts the relayer engine. Once started, the Relayer Engine issues subscription requests to the Spy and begins any other workflows (e.g., tracking missed VAAs). -## Mayan Swift +This will run until the process is killed or encounters an unrecoverable error. To gracefully shut down the relayer, call `app.stop()`. -Mayan Swift is a flexible cross-chain intent protocol that embeds a competitive on-chain price auction to determine the best possible execution for the expressed user intent. +The source code for this example is available in the [`relayer-engine` repository](https://github.com/wormhole-foundation/relayer-engine/blob/main/examples/simple/src/app.ts){target=\_blank}. -### On-Chain Competitive Price Discovery Mechanism +## Start Background Processes -Traditional intent-based protocols essentially function as cross-chain limit orders. If the order is profitable, solvers will compete to fulfill it, leading to MEV-like competition focused on speed. While functional, this methodology presents two clear inefficiencies and drawbacks. +!!! note + These processes _must_ be running for the relayer app below to work. -First, they lack a competitive price discovery mechanism as limit order prices are typically determined through centralized off-chain systems. Second, in this MEV-like market structure, only a single solver can win, while the others lose out on transaction fees. This dynamic of deadweight loss results in solvers prioritizing high-margin orders, ultimately resulting in elevated fees for end-users without commensurate benefits. +Next, you must start a Spy to listen for available VAAs published on the Guardian network. You also need a persistence layer. This example uses Redis. -Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. +More details about the Spy are available in the [Spy Documentation](/docs/protocol/infrastructure/spy){target=\_blank}. -![Mayan Swift - Intent-centric design](/docs/images/learn/transfers/settlement/architecture/architecture-2.webp) +### Wormhole Network Spy -### Protocol Flow: How It Works +For our relayer app to receive messages, a local Spy must be running that watches the Guardian network. Our relayer app will receive updates from this Spy. -1. **Initiation** - the user creates an order by signing a transaction that locks one of the primary assets (USDC or ETH) into the Mayan smart contract, specifying the desired outcome. +=== "Mainnet Spy" - !!!note - If the input asset is not a primary asset, it is converted into a primary asset within the same transaction before the order is submitted. + ```bash + docker run --pull=always --platform=linux/amd64 \ + -p 7073:7073 \ + --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ + spy \ + --nodeKey /node.key \ + --spyRPC "[::]:7073" \ + --env mainnet + ``` - Each order includes properties such as destination chain, destination wallet address, output token address, minimum output amount, gas drop amount, deadline, and 32 bytes of random hex to prevent collisions. A Keccak-256 hash is then calculated to identify the order +=== "Testnet Spy" -2. **Auction** - solvers observe on-chain data or subscribe to the Mayan explorer web socket (solvers using the Mayan explorer verify the order's integrity by checking the data against the on-chain hash). Once the new order is verified, an on-chain auction on Solana is initiated by passing the order ID and the bid amount, which cannot be lower than the minimum amount. Other solvers can increase the bid by submitting a higher amount before the auction ends -3. **Fulfillment** - the auction ends three seconds after the initial bid. Once the auction ends, the winning solver can execute an instruction that passes their wallet address on the destination chain. This triggers a Wormhole message containing the order ID and the winner's wallet address. Wormhole Guardians then sign this message, allowing the winning solver to fulfill the order on the destination chain by submitting proof of their win and the promised amount to the Mayan contract before the deadline. The Mayan contract deducts a protocol fee (currently 3 basis points) and a referral fee (if applicable), transferring the remaining amount to the user's destination wallet. It also triggers a Wormhole message as proof of fulfillment -4. **Settlement** - after the Wormhole Guardians sign the fulfillment message, the winning solver can submit this message on the source chain to unlock the user's funds and transfer them to their own wallet. Upon fulfillment, the solver has the option to delay triggering a Wormhole message immediately. Instead, they can batch the proofs and, once the batch reaches a certain threshold, issue a batched proof to unlock all orders simultaneously, saving on gas fees + ```bash + docker run --pull=always --platform=linux/amd64 \ + -p 7073:7073 \ + --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ + spy \ + --nodeKey /node.key \ + --spyRPC "[::]:7073" \ + --env testnet + ``` -## Mayan MCTP +### Redis Persistence -Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. +!!! note + While you're using [Redis](https://redis.io/docs/latest/develop/get-started/){target=\_blank} here, the persistence layer can be swapped out for some other database by implementing the appropriate [interface](https://github.com/wormhole-foundation/relayer-engine/blob/main/relayer/storage/redis-storage.ts){target=\_blank}. -![Mayan MCTP diagram](/docs/images/learn/transfers/settlement/architecture/architecture-3.webp) +A Redis instance must also be available to persist job data for fetching VAAs from the Spy. -### Protocol Flow: How It Works +```bash +docker run --rm -p 6379:6379 --name redis-docker -d redis +``` -1. **Initiation** - the user creates an order by signing a transaction that locks one USDC into the Mayan smart contract, specifying the desired outcome. +## Use the Wormhole SDK - !!!note - If the input asset is not USDC, it is converted into a primary asset within the same transaction before the order is submitted. +!!! note + The example below uses the legacy [`@certusone/wormhole-sdk`](https://www.npmjs.com/package/@certusone/wormhole-sdk){target=\_blank}, which is still supported and used in the Relayer Engine but is no longer actively maintained. - The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash + For most use cases, it is recommend to use the latest [`@wormhole-foundation/sdk`](https://www.npmjs.com/package/@wormhole-foundation/sdk){target=\_blank}. -2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} -3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules +You can also use the Wormhole SDK to poll the Guardian RPC until a signed VAA is ready using the SDK's `getSignedVAAWithRetry` function. -The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. +```ts +import { + getSignedVAAWithRetry, + parseVAA, + CHAIN_ID_SOLANA, + CHAIN_ID_ETH, +} from '@certusone/wormhole-sdk'; -## Where to Go Next +const RPC_HOSTS = [ + /* ...*/ +]; -- To learn more about available EVM functions, see the [Build on the Wormhole Liquidity Layer](/docs/build/transfers/settlement/liquidity-layer/){target=\_blank} guide -- To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial ---- END CONTENT --- +async function getVAA( + emitter: string, + sequence: string, + chainId: number +): Promise { + // Wait for the VAA to be ready and fetch it from the guardian network + const { vaaBytes } = await getSignedVAAWithRetry( + RPC_HOSTS, + chainId, + emitter, + sequence + ); + return vaaBytes; +} -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlement -description: Learn about Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. -categories: Settlement, Transfer ---- +const vaaBytes = await getVAA('INSERT_EMITTER_ADDRESS', 1, CHAIN_ID_ETH); + +``` -# Wormhole Settlement +Once you have the VAA, the delivery method is chain-dependent. -## Get Started +=== "EVM" -This section covers Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. + On EVM chains, the bytes for the VAA can be passed directly as an argument to an ABI method. -
+ ```ts + // Set up eth wallet +const ethProvider = new ethers.providers.StaticJsonRpcProvider( + 'INSERT_RPC_URL' +); +const ethWallet = new ethers.Wallet('INSERT_PRIVATE_KEY', ethProvider); -- :octicons-question-16:{ .lg .middle } **Overview** +// Create client to interact with our target app +const ethHelloWorld = HelloWorld__factory.connect( + 'INSERT_CONTRACT_ADDRESS', + ethWallet +); - --- +// Invoke the receiveMessage on the ETH contract and wait for confirmation +const receipt = await ethHelloWorld + .receiveMessage(vaaBytes) + .then((tx: ethers.ContractTransaction) => tx.wait()) + .catch((msg: any) => { + console.error(msg); + return null; + }); + ``` - Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. +=== "Solana" - [:custom-arrow: Learn more about Wormhole Settlement](/docs/learn/transfers/settlement/overview/) + On Solana, the VAA is first posted to the core bridge, and then a custom transaction is prepared to process and validate the VAA. -- :octicons-question-16:{ .lg .middle } **Protocol Architectures** + ```ts + import { CONTRACTS } from '@certusone/wormhole-sdk'; - --- +export const WORMHOLE_CONTRACTS = CONTRACTS[NETWORK]; +export const CORE_BRIDGE_PID = new PublicKey(WORMHOLE_CONTRACTS.solana.core); - Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP — for scalable, efficient cross-chain asset transfers. +// First, post the VAA to the core bridge +await postVaaSolana( + connection, + wallet.signTransaction, + CORE_BRIDGE_PID, + wallet.key(), + vaaBytes +); - [:custom-arrow: Discover protocol architectures](/docs/learn/transfers/settlement/architecture/) +const program = createHelloWorldProgramInterface(connection, programId); +const parsed = isBytes(wormholeMessage) + ? parseVaa(wormholeMessage) + : wormholeMessage; -
+const ix = program.methods + .receiveMessage([...parsed.hash]) + .accounts({ + payer: new PublicKey(payer), + config: deriveConfigKey(programId), + wormholeProgram: new PublicKey(wormholeProgramId), + posted: derivePostedVaaKey(wormholeProgramId, parsed.hash), + foreignEmitter: deriveForeignEmitterKey(programId, parsed.emitterChain), + received: deriveReceivedKey( + programId, + parsed.emitterChain, + parsed.sequence + ), + }) + .instruction(); + +const transaction = new Transaction().add(ix); +const { blockhash } = await connection.getLatestBlockhash(commitment); +transaction.recentBlockhash = blockhash; +transaction.feePayer = new PublicKey(payerAddress); + +const signed = await wallet.signTxn(transaction); +const txid = await connection.sendRawTransaction(signed); + +await connection.confirmTransaction(txid); + ``` --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/learn/transfers/settlement/overview/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure-guides/run-spy/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement Overview -description: Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. -categories: Settlement, Transfer +title: Run a Spy +description: Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. --- -# Wormhole Settlement Overview +# Run a Spy ## Introduction -Wormhole Settlement is a fast, institutional-scale digital asset settlement — a new way to transfer assets across chains. - -With Wormhole Settlement, an intent-based asset transfer for individual users and institutions, you can swap, bridge, and build across multiple chains. You can implement cross-chain functionality within your dApps extremely simply and without compromising user experience, widening the horizons of your product offerings and the number and type of users you can cater to. +The Spy is a lightweight component in the Wormhole infrastructure designed to listen for and forward messages (Verifiable Action Approvals (VAAs)) published on the Wormhole network. Running a Spy locally allows developers to subscribe to a filtered stream of these messages, facilitating the development of custom relayers or other integrations with Wormhole. -The Settlement supports Ethereum, Ton, Optimism, Arbitrum, Base, Avalanche, Unichain, Polygon, Solana, and Sui, with many more on the horizon. It is powered by Wormhole Messaging, Wormhole Native Token Transfer (NTT), and Circle's CCTP and built in collaboration with the intent experts at Mayan Finance. +For a more comprehensive understanding of the Spy and its role within the Wormhole ecosystem, refer to the [Spy Documentation](/docs/protocol/infrastructure/spy/){target=\_blank}. -Settlement represents Wormhole's first step towards optimizing the bridging experience and building a product that users and institutions use daily. Use it to send assets between chains, rebalance institutional inventories on-chain cheaply and quickly, or allow your application to be accessible by any user no matter what assets they hold or what chain they call home. +## How to Start a Spy -## Key Features +To start a Spy locally, run the following Docker command: -- **Integrator flexibility** - apps leveraging the SDK can select any one of three potential routes surfaced, each with its tradeoffs concerning time vs cost; they may extend this to users as well -- **Scalable liquidity** - taking into account the sometimes idiosyncratic yet sharp inflows into the Solana ecosystem, the hub-spoke model of the Wormhole Liquidity Layer and the flexible design of Swift are designed for capital efficiency -- **Arbitrary payload support** - integrators can bundle `callData` containing arbitrary protocol actions to enable seamless one-click user experiences, such as swap plus stake +=== "Mainnet" -## Integrator Paths + ```sh + docker run --pull=always --platform=linux/amd64 \ + -p 7073:7073 \ + --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ + spy \ + --nodeKey /node.key \ + --spyRPC "[::]:7073" \ + --env mainnet + ``` -### SDK Integrators +=== "Testnet" -Wormhole provides an SDK that enables apps to abstract away the complexity of cross-chain token swaps. The SDK handles route discovery, fee estimation, and transaction construction. Apps can embed this feature in their backend or create an interface for users to bridge into their respective ecosystems quickly. + ```sh + docker run --pull=always --platform=linux/amd64 \ + -p 7073:7073 \ + --entrypoint /guardiand ghcr.io/wormhole-foundation/guardiand:latest \ + spy \ + --nodeKey /node.key \ + --spyRPC "[::]:7073" \ + --env testnet + ``` -### NTT Integrators +If you want to run the Spy built from source, change `ghcr.io/wormhole-foundation/guardiand:latest` to `guardian` after building the `guardian` image. -NTT partners, current and future, can leverage Wormhole Settlement for near-instant NTT transfers from any chain, including Ethereum mainnet and its L2s. This eliminates waiting for slow source chain confirmation times (sometimes 15 minutes or more). If interested, please [fill out this interest form](https://wormhole.com/contact){target=\_blank}. +Optionally, add the following flags to skip any VAAs with invalid signatures: -### Chain Integrators +=== "Mainnet" -Due to the hub-spoke model of liquidity, new chains without proven traction can access the same level of liquidity for cross-chain intent fulfillment from day one of mainnet launch as established ecosystems with clear evidence of adoption. + ```sh + --ethRPC https://eth.drpc.org + --ethContract 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B + ``` -!!!tip - Looking to integrate Wormhole Settlement? If you're ready, check out how to [integrate Wormhole Settlement Routes using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank}. +=== "Testnet" -## Related Resources + ```sh + --ethRPC https://sepolia.drpc.org/ + --ethContract 0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78 + ``` -- To learn more about the architecture of Wormhole-native swap protocols, see the [Settlement Protocol Architectures](/docs/learn/transfers/settlement/architecture/){target=\_blank} page ---- END CONTENT --- +Optionally, add the following flags to prevent unbounded log growth: -Doc-Content: https://wormhole.com/docs/learn/transfers/token-bridge/ ---- BEGIN CONTENT --- ---- -title: Token Bridge -description: Learn about Wormhole's Token Bridge for cross-chain transfers using lock and mint mechanisms, ensuring secure and efficient asset movement. -categories: Token-Bridge, Transfer ---- +```sh +--log-opt max-size=10m \ +--log-opt max-file=3 +``` -# Token Bridge +## Subscribe to Filtered VAAs -Transferring tokens across blockchain networks is challenging due to the lack of interoperability. Maintaining token properties such as value, name, and precision while ensuring security during transfers often requires complex and costly solutions like liquidity pools or native swaps, which can introduce inefficiencies and risks. +Once running, a [gRPC](https://grpc.io/){target=\_blank} client (i.e., your program) can subscribe to a filtered stream of messages (VAAs). -Wormhole’s Token Bridge addresses these challenges by providing a decentralized protocol for seamless cross-chain token transfers through a lock-and-mint mechanism. Using Wormhole’s message-passing protocol, the Token Bridge allows standards-compliant tokens, like ERC-20 on Ethereum or SPL on Solana, to be transferred between different blockchains while preserving their original attributes. +Use this [proto-spec file](https://github.com/wormhole-foundation/wormhole/blob/main/proto/spy/v1/spy.proto){target=\_blank} to generate a client for the gRPC service. -Offering a more efficient, scalable, and secure alternative to traditional solutions, the Token Bridge ensures that assets retain their properties across multiple blockchain ecosystems. Additionally, it supports flexible features like [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, enabling custom interactions by allowing tokens to carry additional data for smart contract integration on the destination chain. +## Data Persistence -This page introduces the core concepts and functions of Wormhole’s Token Bridge, explaining how it operates, its key features, and how it enables secure and efficient cross-chain token transfers. +The Spy does not have a built-in persistence layer, so it is typically paired with something like Redis or an SQL database to record relevant messages. -### How Does It Work? +The persistence layer needs to implement the appropriate interface. For example, you can check out the [Redis interface](https://github.com/wormhole-foundation/relayer-engine/blob/main/relayer/storage/redis-storage.ts){target=\_blank} used by the Relayer Engine, a package that implements a client and persistence layer for messages received from a Spy subscription. +--- END CONTENT --- -At the core of the Token Bridge lies the lock-and-mint mechanism, which uses the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} with a specific [payload](/docs/learn/infrastructure/vaas/#token-transfer){target=\_blank} to pass information about the transfer. Tokens on the source chain are locked, and wrapped tokens are minted on the destination chain. This approach guarantees that token transfers are secure and consistent, ensuring that token properties such as name, symbol, and decimal precision are preserved across chains. +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/core-contracts/ +--- BEGIN CONTENT --- +--- +title: Core Contracts +description: Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +categories: Basics +--- -Before a token can be transferred to a new chain, the token’s metadata must be [attested](/docs/learn/infrastructure/vaas/#attestation){target=\_blank}. This process registers the token details (such as decimals and symbol) on the destination chain, enabling the creation of wrapped assets. +# Core Contracts -While the [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} has no specific receiver by default, transfers sent through the Token Bridge do have a specific receiver chain and address to ensure the tokens are minted to the expected recipient. +## Introduction -In addition to standard token transfers, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}. This functionality allows users to attach additional data to token transfers, enabling more complex interactions with smart contracts on the destination chain. For instance, a token transfer can include a payload that triggers specific actions, such as interacting with a decentralized exchange (DEX) or automated market maker (AMM). +The Wormhole Core Contract is deployed across each supported blockchain network. This contract is a fundamental component of the Wormhole interoperability protocol and acts as the foundational layer enabling secure and efficient multichain messaging. All multichain applications either interact directly with the Core Contract or with another contract that does. -### Token Transfer Flow +This page summarizes the key functions of the Core Contract and outlines how the Core Contract works. -The transfer process is simple yet secure, involving a few key steps: +## Key Functions -1. **Attestation** - first, a token's metadata is attested on the source chain, ensuring that its properties are consistent across chains -2. **Locking** - on the source chain, the native token is locked in a custody account -3. **Message emission** - a message detailing the transfer is sent through Wormhole’s Guardian Network, which verifies the transfer and signs the message -4. **Verification and minting** - on the destination chain, the transfer message is verified, and wrapped tokens are minted, or native tokens are released from custody +Key functions of the Wormhole Core Contract include the following: -![Token Bridge detailed flow](/docs/images/learn/transfers/token-bridge/token-bridge-diagram.webp) +- **Multichain messaging** - standardizes and secures the format of messages to facilitate consistent communication for message transfer between Wormhole-connected blockchain networks, allowing developers to leverage the unique features of each network +- **Verification and validation** - verifies and validates all VAAs received on the target chain by confirming the Guardian signature to ensure the message is legitimate and has not been manipulated or altered +- **Guardian Network coordination** - coordinates with Wormhole's Guardian Network to facilitate secure, trustless communication across chains and ensure that only validated interactions are processed to enhance the protocol's overall security and reliability +- **Event emission for monitoring** - emits events for every multichain message processed, allowing for network activity monitoring like tracking message statuses, debugging, and applications that can react to multichain events in real time -### Key Features of the Token Bridge +## How the Core Contract Works -The Token Bridge creates wrapped versions when tokens are transferred to a different chain. These wrapped assets represent the locked tokens on the source chain and allow users to interact with them on the destination chain. This mechanism ensures seamless functionality without needing liquidity pools or native token swaps. +The Wormhole Core Contract is central in facilitating secure and efficient multichain transactions. It enables communication between different blockchain networks by packaging transaction data into standardized messages, verifying their authenticity, and ensuring they are executed correctly on the destination chain. -The Token Bridge employs a universal token representation that is compatible with various virtual machine (VM) data types. This allows the tokens to interact with decentralized applications (dApps) across different chains without issues related to differing token standards. +The following describes the role of the Wormhole Core Contract in message transfers: -### Message and Payload Structure +1. **Message submission** - when a user initiates a multichain transaction, the Wormhole Core Contract on the source chain packages the transaction data into a standardized message payload and submits it to the Guardian Network for verification +2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -To facilitate cross-chain communication, the Token Bridge uses specialized payloads that carry the necessary information for token transfers and attestations. These payloads ensure that the correct tokens are minted or unlocked on the destination chain. +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. -- `Transfer` - this payload initiates the transfer of tokens, either by minting wrapped tokens or releasing locked tokens -- `TransferWithPayload` - in addition to transferring tokens, this payload carries additional data, allowing integration with smart contracts or dApps on the target chain -- `AssetMeta` - before a token can be transferred for the first time, this payload is used to attest to the token’s metadata, including decimals, symbol, and name -- `RegisterChain` - register the Token Bridge contract (emitter address) for a foreign chain -- `UpgradeContract` - upgrade the contract +### Message Submission -Each payload type is designed to serve a specific function in the token transfer process, ensuring that the bridge operates efficiently and securely. +You can send multichain messages by calling a function against the source chain Core Contract, which then publishes the message. Message publishing strategies can differ by chain; however, generally, the Core Contract posts the following items to the blockchain logs: -One of the key challenges in cross-chain token transfers is maintaining the correct token precision. The Token Bridge addresses this using the `AssetMeta` payload to store token metadata. Before transferring a token to a new chain, metadata such as its decimal precision, name, and symbol must be attested. The bridge ensures token amounts are truncated to a maximum of 8 decimals, guaranteeing compatibility with chains that may not support higher decimal precision. For example, an 18-decimal token on Ethereum will be represented with only eight decimals on the destination chain, simplifying integration with various decentralized applications. +- `emitterAddress` - the contract which made the call to publish the message +- `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page -### Security and Authorization +There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. -The Token Bridge uses an emitter chain and address authorization system to verify the validity of messages. Each Token Bridge endpoint is registered on its respective chain, ensuring only trusted contracts can send or receive transfer messages. +### Message Reception -The [Wormhole Guardian Network](/docs/learn/infrastructure/guardians/#guardian-network){target=\_blank} plays a critical role in verifying each transfer and ensuring that the message is signed and relayed securely between chains. +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. -### Portal Bridge +## Multicast -A real-world example of Wormhole's Token Bridge in action is the [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides users with a simple interface to transfer tokens across multiple blockchains. Using the Wormhole infrastructure, Portal Bridge guarantees secure and seamless cross-chain transfers, making it easier for users to move assets between different blockchain ecosystems. ---- END CONTENT --- +Multicast refers to simultaneously broadcasting a single message or transaction across different blockchains with no destination address or chain for the sending and receiving functions. VAAs attest that "this contract on this chain said this thing." Therefore, VAAs are multicast by default and will be verified as authentic on any chain where they are used. -Doc-Content: https://wormhole.com/docs/tutorials/connect/ ---- BEGIN CONTENT --- ---- -title: Wormhole Connect Tutorials -description: Enable cross-chain connectivity with Wormhole Connect. Learn integration and simplify user experiences across multiple blockchains. -categories: Connect, Transfer ---- +This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -# Connect +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. -Wormhole Connect makes it simple to link your application to multiple blockchain ecosystems. These tutorials will teach you how to integrate Connect into your projects, streamline cross-chain interactions, simplify user onboarding, and deliver a smoother overall experience. +Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. -## Tutorials +## Next Steps
-- :octicons-repo-16:{ .lg .middle } **Integrate Connect into a React DApp** +- :octicons-book-16:{ .lg .middle } **Verified Action Approvals (VAA)** --- - Learn how to incorporate Wormhole Connect into a React application. This step-by-step tutorial guides you through enabling cross-chain token transfers and interactions, bridging assets between networks, and enhancing the user experience with streamlined blockchain connectivity. - - [:custom-arrow: Start building](/docs/tutorials/connect/react-dapp/) - -
- -## Additional Resources + Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. -
+ [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) -- :octicons-tools-16:{ .lg .middle } **Connect** +- :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** --- - Get deeper insights into setting up and customizing Wormhole Connect. Explore advanced guides, best practices, and configuration tips to streamline your cross-chain integrations. + This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Learn more](/docs/build/transfers/connect/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/connect/react-dapp/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/guardians/ --- BEGIN CONTENT --- --- -title: Integrate Connect into a React DApp Tutorial -description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. -categories: Connect, Transfer +title: Guardians +description: Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +categories: Basics --- -# Integrate Connect into a React DApp +## Guardian -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} +Wormhole relies on a set of 19 distributed nodes that monitor the state on several blockchains. In Wormhole, these nodes are referred to as Guardians. The current Guardian set can be seen in the [Dashboard](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank}. -## Introduction +Guardians fulfill their role in the messaging protocol as follows: -In this tutorial, we’ll explore how to integrate [Wormhole Connect](https://github.com/wormhole-foundation/wormhole-connect){target=\_blank} to enable cross-chain token transfers and interactions. Wormhole Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Wormhole Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. +1. Each Guardian observes messages and signs the corresponding payloads in isolation from the other Guardians +2. Guardians combine their independent signatures to form a multisig +3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any blockchain supported by Wormhole. In this example, we’ll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). -## Prerequisites +## Guardian Network -To get started with Wormhole Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. -Before starting this tutorial, ensure you have the following: +The Guardian Network functions as Wormhole's decentralized oracle, ensuring secure, cross-chain interoperability. Learning about this critical element of the Wormhole ecosystem will help you better understand the protocol. -- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine -- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use -- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} -- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees +The Guardian Network is designed to help Wormhole deliver on five key principles: -## Set Up Connect for Sui Transfers +- **Decentralization** - control of the network is distributed across many parties +- **Modularity** - independent components (e.g., oracle, relayer, applications) ensure flexibility and upgradeability +- **Chain agnosticism** - supports EVM, Solana, and other blockchains without relying on a single network +- **Scalability** - can handle large transaction volumes and high-value transfers +- **Upgradeable** - can change the implementation of its existing modules without breaking integrators to adapt to changes in decentralized computing -### Create a React Project +The following sections explore each principle in detail. -Start by setting up your React app: +### Decentralization -1. Open your terminal and run the following command to create a new React app: +Decentralization remains the core concern for interoperability protocols. Earlier solutions were fully centralized, and even newer models often rely on a single entity or just one or two actors, creating low thresholds for collusion or failure. - ```bash - npx create-react-app connect-tutorial - ``` +Two common approaches to decentralization have notable limitations: -2. Navigate into the project directory: +- **Proof-of-Stake (PoS)** - while PoS is often seen as a go-to model for decentralization, it's not well-suited for a network that verifies many blockchains and doesn't run its own smart contracts. Its security in this context is unproven, and it introduces complexities that make other design goals harder to achieve +- **Zero-Knowledge Proofs (ZKPs)** - ZKPs offer a trustless and decentralized approach, but the technology is still early-stage. On-chain verification is often too computationally expensive—especially on less capable chains—so a multisig-based fallback is still required for practical deployment - ```bash - cd connect-tutorial - ``` +In the current De-Fi landscape, most major blockchains are secured by a small group of validator companies. Only a limited number of companies worldwide have the expertise and capital to run high-performance validators. -### Install Wormhole Connect +If a protocol could unite many of these top validator companies into a purpose-built consensus mechanism designed for interoperability, it would likely offer better performance and security than a token-incentivized network. The key question is: how many of them could Wormhole realistically involve? -Next, install the Wormhole Connect package as a dependency by running the following command inside your project directory: +To answer that, consider these key constraints and design decisions: -```bash -npm install @wormhole-foundation/wormhole-connect -``` +- **Threshold signatures allow flexibility, but** - with threshold signatures, in theory, any number of validators could participate. However, threshold signatures are not yet widely supported across blockchains. Verifying them is expensive and complex, especially in a chain-agnostic system +- **t-Schnorr multisig is more practical** - Wormhole uses [t-Schnorr multisig](https://en.wikipedia.org/wiki/Schnorr_signature){target=\_blank}, which is broadly supported and relatively inexpensive to verify. However, verification costs scale linearly with the number of signers, so the size of the validator set needs to be carefully chosen +- **19 validators is the optimal tradeoff** - a set of 19 participants presents a practical compromise between decentralization and efficiency. With a two-thirds consensus threshold, only 13 signatures must be verified on-chain—keeping gas costs reasonable while ensuring strong security +- **Security through reputation, not tokens** - Wormhole relies on a network of established validator companies instead of token-based incentives. These 19 Guardians are among the most trusted operators in the industry—real entities with a track record, not anonymous participants -### Integrate Connect into the Application +This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus model, where each Guardian has an equal stake. As threshold signatures gain broader support, the set can expand. Once ZKPs become widely viable, the network can evolve into a fully trustless system. -Now, we need to modify the default `App.js` file to integrate Wormhole Connect. We are going to use [version V1.0](/docs/build/transfers/connect/upgrade/){target=\_blank}, make sure to check which version of connect you are using. Open `src/App.js` and replace the content with the following code: +### Modularity -=== "JavaScript" +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. - ```js - import logo from './logo.svg'; - import './App.css'; - import WormholeConnect from '@wormhole-foundation/wormhole-connect'; +### Chain Agnosticism - const config = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], - }; +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. - function App() { - return ; - } +### Scalability - export default App; - ``` +Wormhole scales well, as demonstrated by its ability to handle substantial total value locked (TVL) and transaction volume even during tumultuous events. -=== "TypeScript" +Every Guardian must run a full node for every blockchain in the ecosystem. This requirement can be computationally heavy to set up; however, once all the full nodes are running, the Guardian Network's actual computation needs become lightweight. - ```ts - import './App.css'; - import WormholeConnect, { - WormholeConnectConfig, - WormholeConnectTheme, - } from '@wormhole-foundation/wormhole-connect'; +Performance is generally limited by the speed of the underlying blockchains, not the Guardian Network itself. - function App() { - const config: WormholeConnectConfig = { - network: 'Testnet', - chains: ['Sui', 'Avalanche'], +### Upgradeable - ui: { - title: 'SUI Connect TS Demo', - }, - }; +Wormhole is designed to adapt and evolve in the following ways: - const theme: WormholeConnectTheme = { - mode: 'dark', - primary: '#78c4b6', - }; +- **Guardian Set expansion** – future updates may introduce threshold signatures to allow for more Guardians in the set +- **ZKP integration** - as Zero-Knowledge Proofs become more widely supported, the network can transition to a fully trustless model - return ; - } +These principles combine to create a clear pathway towards a fully trustless interoperability layer that spans decentralized computing. - export default App; - ``` +## Next Steps -- Set `network` to `testnet` - this ensures that Wormhole Connect uses the testnet environment -- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche +
-### Customize Wormhole Connect +- :octicons-book-16:{ .lg .middle } **Relayers** -To further customize Wormhole Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Wormhole Connect Configuration guide](/docs/build/transfers/connect/configuration/#introduction){target=\_blank}. + --- -### Run the Application + Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -Make sure you’re in the root directory of your React app, and run the following command to start the application: + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) -```bash -npm start -``` +- :octicons-tools-16:{ .lg .middle } **Query Guardian Data** -Now your React app should be up and running, and Wormhole Connect should be visible on `http://localhost:3000/`. You should see the Wormhole Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. + --- -## Transfer Tokens from Sui to Fuji + Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. -Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) -To transfer tokens from Sui to Fuji in the Wormhole Connect interface: +
+--- END CONTENT --- -1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer -2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network -3. Enter the amount of SUI tokens you wish to transfer +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/relayer/ +--- BEGIN CONTENT --- +--- +title: Relayers +description: Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +categories: Basics +--- - ![](/docs/images/tutorials/connect/react-dapp/connect-1.webp) +# Relayers -4. Choose to view other routes - - ![](/docs/images/tutorials/connect/react-dapp/connect-2.webp) +This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. - !!! note - It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. +There are three primary types of relayers discussed: - ![](/docs/images/tutorials/connect/react-dapp/connect-3.webp) +- **Client-side relaying** - a cost-efficient, no-backend-infrastructure approach relying on user-facing front ends. It provides a simple solution, although it can complicate the user experience due to the manual steps involved -6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain +- **Custom relayers** - backend components that handle parts of the cross-chain process, offering a smoother user experience and allowing off-chain calculations to reduce gas costs. These relayers could operate through direct listening to the Guardian Network (Spy relaying) - ![](/docs/images/tutorials/connect/react-dapp/connect-4.webp) +- **Wormhole-deployed relayers** - a decentralized relayer network that can deliver arbitrary VAAs, reducing the developer's need to develop, host, or maintain relayers. However, they require all calculations to be done on-chain and might be less gas-efficient -7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet +## Fundamentals - ![](/docs/images/tutorials/connect/react-dapp/connect-5.webp) +This section highlights the crucial principles underpinning the operation and handling of relayers within the Wormhole network. -Once the transaction has been submitted, Wormhole Connect will display the progress of the transfer. Monitor the status until you’re prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. +Relayers are fundamentally trustless entities within the network, meaning while they don't require your trust to operate, you also shouldn't trust them implicitly. Relayers function as delivery mechanisms, transporting VAAs from their source to their destination. -## Claim Tokens on Fuji +Key characteristics of VAAs include: -After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. +- Public emission from the Guardian Network -![](/docs/images/tutorials/connect/react-dapp/connect-6.webp) +- Authentication through signatures from the Guardian Network -Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. +- Verifiability by any entity or any Wormhole Core Contract -![](/docs/images/tutorials/connect/react-dapp/connect-7.webp) +These characteristics mean anyone can pick up a VAA and deliver it anywhere, but no one can alter the VAA content without invalidating the signatures. -## Resources +Keep in mind the following security considerations around relayers: -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Wormhole Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. +- **Trusting information** - it is crucial not to trust information outside your contract or a VAA. Relying on information from a relayer could expose you to input attacks -## Conclusion +- **Gas optimization** - using relayers to perform trustless off-chain computation to pass into the destination contract can optimize gas costs but also risk creating attack vectors if not used correctly -In this tutorial, you’ve gained hands-on experience with integrating Wormhole Connect to enable cross-chain token transfers. You’ve learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. +- **Deterministic by design** - the design of a relayer should ensure a single, deterministic way to process messages in your protocol. Relayers should have a "correct" implementation, mirroring "crank turner" processes used elsewhere in blockchain -By following these steps, you've learned how to: +## Client-Side Relaying -- Set up a React project tailored for cross-chain transfers -- Install and configure Wormhole Connect to support multiple blockchains -- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers -- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks +Client-side relaying relies on user-facing front ends, such as a webpage or a wallet, to complete the cross-chain process. -With these tools and knowledge, you’re now equipped to build powerful cross-chain applications using Wormhole Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. ---- END CONTENT --- +### Key Features -Doc-Content: https://wormhole.com/docs/tutorials/ ---- BEGIN CONTENT --- ---- -title: Tutorials -description: Discover product-specific Wormhole tutorials. Learn setup, integration, and advanced features to develop cross-chain apps confidently. -template: root-index-page.html ---- +- **Cost-efficiency** - users only pay the transaction fee for the second transaction, eliminating any additional costs -# Tutorials +- **No backend infrastructure** - the process is wholly client-based, eliminating the need for a backend relaying infrastructure -In this section, you'll find tutorials focused on individual Wormhole products. Each product folder contains detailed guides to help you integrate and use specific Wormhole services, such as Token Bridge, Wormhole Connect, and more. Whether setting up your first product or diving deeper into advanced features, these tutorials will walk you through the entire process, from installation to implementation. +### Implementation -## Browse Tutorials by Product +Users themselves carry out the three steps of the cross-chain process: -## Get Started +1. Perform an action on chain A -
+2. Retrieve the resulting VAA from the Guardian Network -- :octicons-arrow-switch-16:{ .lg .middle } **Connect** +3. Perform an action on chain B using the VAA - --- +### Considerations - With Wormhole Connect, you can enable seamless connectivity between different blockchain ecosystems. These tutorials guide you through integrating Connect into your projects, allowing you to easily leverage cross-chain interactions, simplify onboarding, and improve user experience. +Though simple, this type of relaying is generally not recommended if your aim is a highly polished user experience. It can, however, be useful for getting a Minimum Viable Product (MVP) up and running. - [:custom-arrow: Start building](/docs/tutorials/connect/) +- Users must sign all required transactions with their own wallet -- :octicons-sync-16:{ .lg .middle } **Multichain Assets** +- Users must have funds to pay the transaction fees on every chain involved - --- +- The user experience may be cumbersome due to the manual steps involved - Learn how to create, register, and manage wrapped multichain assets across multiple chains. These tutorials will guide you through the process of enabling asset transfers between supported networks. +## Custom Relayers - [:custom-arrow: Start building](/docs/tutorials/multichain-assets/) +Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -- :octicons-people-16:{ .lg .middle } **MultiGov** +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). - --- +### Key Features - Unleash the power of cross-chain governance with Multigov. These tutorials guide you through setting up and managing governance structures spanning multiple blockchains, enabling collective decision-making and coordinated upgrades across decentralized ecosystems. +- **Optimization** - capable of performing trustless off-chain computations which can optimize gas costs - [:custom-arrow: Start building](/docs/tutorials/multigov/) +- **Customizability** - allows for specific strategies like batching, conditional delivery, multi-chain deliveries, and more -- :octicons-file-code-16:{ .lg .middle } **Solidity SDK** +- **Incentive structure** - developers have the freedom to design an incentive structure suitable for their application - --- +- **Enhanced UX** - the ability to retrieve a VAA from the Guardian Network and perform an action on the target chain using the VAA on behalf of the user can simplify the user experience - Learn to build smart contracts that communicate across multiple blockchains. These tutorials show you how to create robust cross-chain contracts, allowing your dApps to move beyond a single network and tap into global liquidity, functionality, and user bases. +### Implementation - [:custom-arrow: Start building](/docs/tutorials/solidity-sdk/) +A plugin relayer to make the development of custom relayers easier is available in the [main Wormhole repository](https://github.com/wormhole-foundation/wormhole/tree/main/relayer){target=\_blank}. This plugin sets up the basic infrastructure for relaying, allowing developers to focus on implementing the specific logic for their application. -- :octicons-code-square-16:{ .lg .middle } **TypeScript SDK** +### Considerations - --- +Remember, despite their name, custom relayers still need to be considered trustless. VAAs are public and can be submitted by anyone, so developers shouldn't rely on off-chain relayers to perform any computation considered "trusted." - Master the tools to build cross-chain applications with the Wormhole SDK. These tutorials cover installation to advanced functionality, helping you streamline development, reduce complexity, and quickly bring your ideas to life. +- Development work and hosting of relayers are required - [:custom-arrow: Start building](/docs/tutorials/typescript-sdk/) +- The fee-modeling can become complex, as relayers are responsible for paying target chain fees -- :octicons-code-square-16:{ .lg .middle } **Wormholescan API** +- Relayers are responsible for availability, and adding dependencies for the cross-chain application - --- +## Wormhole Relayers - Explore hands-on tutorials for using the Wormholescan API to retrieve blockchain data, track transactions, validate VAAs, check redemption status, and more. +Wormhole relayers are a component of a decentralized network in the Wormhole protocol. They facilitate the delivery of VAAs to recipient contracts compatible with the standard relayer API. - [:custom-arrow: Start building](/docs/tutorials/wormholescan/) +### Key Features -
---- END CONTENT --- +- **Lower operational costs** - no need to develop, host, or maintain individual relayers -Doc-Content: https://wormhole.com/docs/tutorials/multichain-assets/ ---- BEGIN CONTENT --- ---- -title: Multichain Assets Tutorials -description: Explore comprehensive, step-by-step tutorials on how to register, manage, and work with multichain assets within the Wormhole ecosystem. ---- +- **Simplified integration** - because there is no need to run a relayer, integration is as simple as calling a function and implementing an interface -# Multichain Assets +### Implementation -Multichain assets, often represented as wrapped tokens, enable seamless cross-chain interoperability. This section provides step-by-step tutorials for registering, managing, and working with these assets across different blockchains. +The Wormhole relayer integration involves two key steps: -## Tutorials +- **Delivery request** - request delivery from the ecosystem Wormhole relayer contract -
+- **Relay reception** - implement a [`receiveWormholeMessages`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/bacbe82e6ae3f7f5ec7cdcd7d480f1e528471bbb/src/interfaces/IWormholeReceiver.sol#L44-L50){target=\_blank} function within their contracts. This function is invoked upon successful relay of the VAA -- :octicons-repo-16:{ .lg .middle } **Create Multichain Tokens** +### Considerations - --- +Developers should note that the choice of relayers depends on their project's specific requirements and constraints. Wormhole relayers offer simplicity and convenience but limit customization and optimization opportunities compared to custom relayers. - Learn how to register your token on both a source and target chain, and create a wrapped version for seamless interoperability. +- All computations are performed on-chain - [:custom-arrow: Register your assets now](/docs/tutorials/multichain-assets/multichain-token/) +- Potentially less gas-efficient compared to custom relayers -
---- END CONTENT --- +- Optimization features like conditional delivery, batching, and off-chain calculations might be restricted -Doc-Content: https://wormhole.com/docs/tutorials/multichain-assets/multichain-token/ ---- BEGIN CONTENT --- ---- -title: Create Multichain Tokens -description: Learn how to create a multichain token, bridge tokens across blockchains, and update metadata for seamless multichain interoperability. ---- +- Support may not be available for all chains -# Create Multichain Tokens +## Next Steps -## Introduction +
-Blockchain ecosystems are becoming increasingly interconnected, with assets often needing to exist across multiple networks to maximize their utility and reach. For example, tokens created on one chain may want to expand to others to tap into broader audiences and liquidity pools. +- :octicons-book-16:{ .lg .middle } **Spy** -This guide explains how to create a multichain token—a token that seamlessly bridges across blockchains using the Wormhole protocol. The process is designed to be user-friendly. With just a few steps, your token can become multichain, enabling it to be traded or used on various networks. + --- -By the end of this tutorial, you'll learn: + Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -- How to register your token for bridging -- How to create a wrapped version of your token -- How to ensure its visibility on blockchain explorers + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) -Let’s begin with a straightforward, step-by-step process for creating a multichain token and expanding its reach. +- :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** -## Register the Token on the Source Chain + --- -The first step in creating a multichain token is registering your token on its source chain. This ensures the token is prepared for bridging across blockchains. Follow these steps: + Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -1. Open the [Portal Bridge](https://portalbridge.com/advanced-tools/#/register){target=\_blank} -2. Select the blockchain where your token is currently deployed (source chain) -3. Connect your wallet by following the on-screen instructions -4. Locate the **Asset** field and paste the token contract address -5. Click **Next** to proceed + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) -![Source Chain Registration Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-1.webp) +- :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** -## Register the Token on the Target Chain + --- -After registering your token on the source chain, the next step is to select the target chain—the blockchain where you want the wrapped version of your token to exist. This step connects your token to its destination network. + Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -1. Choose the blockchain where you want the token to be bridged (target chain) -2. Connect your wallet to the target chain -3. Click **Next** to finalize the registration process + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) -![Target Chain Registration Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-2.webp) +
+--- END CONTENT --- -## Send an Attestation -Attestation is a key step in the process. It verifies your token’s metadata, ensuring it is correctly recognized on the target chain’s blockchain explorer (e.g., [Etherscan](https://etherscan.io/){target=\_blank}). +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/spy/ +--- BEGIN CONTENT --- +--- +title: Spy +description: Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +categories: Basics +--- -1. Click **Attest** to initiate the attestation process -2. Approve the transaction in your wallet when prompted +# Spy -![Send Attestation Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-3.webp) +In Wormhole's ecosystem, the _Spy_ is a daemon, a continuously running background process that monitors messages within the Guardian Network. Unlike Guardians, a Spy doesn't perform validation; instead, it serves as an interface for observing the network's message traffic, enabling applications and users to access live data transmitted over Wormhole. -!!! note - - Attestation is crucial for token metadata to appear correctly on blockchain explorers like Etherscan, allowing users to identify and trust your token - - Ensure you have sufficient funds to cover transaction fees on the target chain +The primary purpose of a Spy is to subscribe to the gossiped messages across the Guardian Network, tracking key message types that allow integrators and applications to monitor real-time network activity without directly engaging in consensus operations. -## Create the Wrapped Token +This page provides a comprehensive guide to where the Spy fits within the Wormhole network, describing the key features and role in facilitating multichain processes. -The final step is to create the wrapped token on the target chain. This token represents the original asset and enables its use within the target blockchain. +## Key Features -1. Click **Create** to generate the wrapped token -2. Approve the transaction in your wallet when prompted +- **Real-time monitoring of Wormhole messages** - the Spy allows users to observe Wormhole messages as they are published across supported chains in near real-time +- **Filterable and observable message streams** - users can filter message streams by chain, emitter, and other criteria, making it easier to track specific contracts or categories of interest +- **Integration-friendly event streaming** - the Spy exposes gRPC and WebSocket interfaces, making it easy to integrate message observation into custom tooling, dashboards, or indexing services +- **Support for multiple message protocols** - it can observe messages from different Wormhole messaging protocols (Token Bridge, CCTP, NTT, etc.), providing broad coverage of cross-chain activity +- **Lightweight and infrastructure-ready** - the Spy is designed to run as part of indexing or backend services, not requiring validator-level infrastructure -![Create Wrapped Token Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-4.webp) +## Integrator Use Case -Upon successful creation, you will see a confirmation screen displaying key details such as the source chain, target chain, and transaction status. This helps verify that the process was completed correctly. Refer to the image below as an example: +The Spy provides a valuable mechanism for integrators to observe real-time network activity in the Guardian Network without directly engaging in validation or consensus. By running a Spy, integrators can track multichain events and message flows — such as VAAs, observations, and Guardian heartbeats — to monitor network activity essential to their applications. -![Confirmation Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-5.webp) +This monitoring capability is especially beneficial for applications that need immediate insights into multichain data events. Integrators can run a Spy to ensure their applications are promptly informed of message approvals, observations, or Guardian liveness signals, supporting timely and responsive app behavior without additional overhead on network resources. -## Additional Steps and Recommendations +## Observable Message Categories -After creating your multichain token, there are a few optional but highly recommended steps to ensure the best experience for users interacting with your token. +A Spy can access the following categories of messages shared over the gossip protocol: -### Add Your Token to the Wormhole Metadata List (Legacy) +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data -For legacy compatibility in the [**Advanced Tools**](https://portalbridge.com/advanced-tools/){target=\_blank} section of Portal Bridge, you can request updates to your token metadata. Follow these steps: + - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -1. Join the [Wormhole Discord server](https://discord.com/invite/wormholecrypto){target=\_blank} -2. Submit a request for metadata updates in the appropriate support channel +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network -!!! note - These updates only apply to the **Advanced Tools** section of Portal Bridge and will not update how your token appears in other Wormhole-powered apps or on blockchain explorers like Etherscan. + - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -### Update Metadata on Blockchain Explorers +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status -It is recommended that you update your token’s metadata on blockchain explorers such as Etherscan. This includes adding details like the token logo, price, and contract verification. + - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network -1. Create an account on the relevant scanner and go to the [token update section](https://etherscan.io/tokenupdate){target=\_blank} (or the relevant scanner that you would like to update metadata on) -2. Copy and paste the wrapped contract address in the **Token Update Application Form** -3. Before proceeding to the next step, you will need to verify as the contract address owner on [Etherscan’s address verification tool](https://etherscan.io/verifyAddress/){target=\_blank} -4. Follow the directions to verify contract address ownership via MetaMask by reviewing the [guide on verifying address ownership](https://info.etherscan.com/how-to-verify-address-ownership/){target=\_blank} - - Given that Wormhole may be the contract owner, use the manual verification process by reaching out through the [Etherscan contact form](https://etherscan.io/contactus){target=\_blank}. The team will provide support as needed -5. Once the step above is completed, follow the [instructions to update token information](https://info.etherscan.com/how-to-update-token-information-on-token-page/){target=\_blank} ---- END CONTENT --- +## Additional Resources -Doc-Content: https://wormhole.com/docs/tutorials/multigov/ ---- BEGIN CONTENT --- ---- -title: Step-by-Step MultiGov Tutorials -description: Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. -categories: MultiGov ---- +
-# MultiGov +- :octicons-code-16:{ .lg .middle } **Spy Source Code** -Welcome to the MultiGov tutorials section. In this section, you will find tutorials that walk you through the key steps of working with MultiGov, providing clear instructions to help you get started. As you explore, you'll gain a deeper understanding of MultiGov's features and functionality. + --- -## Tutorials + To see the source code for the Go implementation of the Spy, visit the `wormhole` repository on GitHub. -
+ [:custom-arrow: View the Source Code](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank} + +- :octicons-code-16:{ .lg .middle } **Alternative Implementation** + + --- + + Visit the `beacon` repository on GitHub to learn more about Beacon, an alternative highly available, reduced-latency version of the Wormhole Spy. + + [:custom-arrow: Get Started with Pyth Beacon](https://github.com/pyth-network/beacon) -- :octicons-repo-16:{ .lg .middle } **Cross-Chain Treasury Management Proposal** +- :octicons-book-16:{ .lg .middle } **Discover Wormhole Queries** --- - Learn how to propose governance actions on a hub chain, gather votes from spoke chains, aggregate the results, and carry out the final decision. Following these steps, you’ll master end-to-end governance workflows spanning multiple networks. + For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. - [:custom-arrow: Start building](/docs/tutorials/multigov/treasury-proposal/) + [:custom-arrow: Explore Queries](/docs/products/queries/overview/)
-## Additional Resources +## Next Steps
-- :octicons-book-16:{ .lg .middle } **Governance Fundamentals** +- :octicons-code-16:{ .lg .middle } **Run a Spy** --- - Dive into Wormhole’s governance mechanisms. Understand how cross-chain governance works, proposal creation, voting, and execution. + Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). - [:custom-arrow: Explore governance](/docs/learn/governance/) + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} -- :octicons-tools-16:{ .lg .middle } **Implement MultiGov** +- :octicons-code-16:{ .lg .middle } **Use Queries** --- - Integrate MultiGov into your smart contracts. Access reference code, best practices, and guidance for deploying cross-chain governance systems. - + For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. - [:custom-arrow: Build with MultiGov](/docs/build/multigov/) + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/)
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/multigov/treasury-proposal/ +Doc-Content: https://wormhole.com/docs/protocol/infrastructure/vaas/ --- BEGIN CONTENT --- --- -title: MultiGov Guides -description: Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. -categories: MultiGov +title: VAAs +description: Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +categories: Basics --- -# Cross-Chain treasury management proposal +# Verified Action Approvals -This guide walks through the process of creating and executing a cross-chain governance proposal to mint W tokens to both the Optimism and Arbitrum treasuries. In this tutorial, we'll cover how to create a proposal on the hub chain (Ethereum Mainnet), cast votes from spoke chains (Optimism and Arbitrum), aggregate votes, and execute the proposal. +Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -## Create a Proposal +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. -The first step is to create a proposal on the hub chain, which in this case is Ethereum Mainnet. The proposal will contain instructions to mint 10 W tokens to the Optimism treasury and 15 ETH to the Arbitrum treasury. +The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. -In the following code snippet, we initialize the proposal with two transactions, each targeting the Hub's Message Dispatcher contract. These transactions will relay the governance actions to the respective spoke chains via Wormhole. +VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the [Wormholescan API](https://docs.wormholescan.io/){target=\_blank} with this information. -Key actions: +The `sequence` field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side. + +The tuple (`emitter_chain`, `emitter_address`, `sequence`) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number. -- Define the proposal targets (two transactions to the Message Dispatcher) -- Set values for each transaction (in this case, both are 0 as we're not transferring any native ETH) -- Encode the calldata for minting 10 W tokens on Optimism and sending 15 ETH to Arbitrum -- Finally, we submit the proposal to the `HubGovernor` contract +## VAA Format -```solidity -HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); -// Prepare proposal details -address[] memory targets = new address[](2); -targets[0] = HUB_MESSAGE_DISPATCHER_ADDRESS; -targets[1] = HUB_MESSAGE_DISPATCHER_ADDRESS; -uint256[] memory values = new uint256[](2); -values[0] = 0; -values[1] = 0; -bytes[] memory calldatas = new bytes[](2); -// Prepare message for Optimism to mint 10 W tokens -// bytes created using abi.encodeWithSignature("mint(address,uint256)", 0xB0fFa8000886e57F86dd5264b9582b2Ad87b2b91, 10e18) -calldatas[0] = abi.encodeWithSignature( - "dispatch(bytes)", - abi.encode( - OPTIMISM_WORMHOLE_CHAIN_ID, - [OPTIMISM_WORMHOLE_TREASURY_ADDRESS], - [uint256(10 ether)], - [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] - ) -); -// Prepare message for Arbitrum to receive 15 ETH -calldatas[1] = abi.encodeWithSignature( - "dispatch(bytes)", - abi.encode( - ARBITRUM_WORMHOLE_CHAIN_ID, - [ARBITRUM_WORMHOLE_TREASURY_ADDRESS], - [uint256(15 ether)], - [hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"] - ) -); -string memory description = "Mint 10 W to Optimism treasury and 10 W to Arbitrum treasury via Wormhole"; -// Create the proposal -uint256 proposalId = governor.propose( - targets, values, calldatas, description -) -``` - -??? interface "Parameters" +The basic VAA consists of header and body components described as follows: - `GOVERNOR_ADDRESS` ++"address"++ +- **Header** - holds metadata about the current VAA, the Guardian set that is currently active, and the list of signatures gathered so far + - `version` ++"byte"++ - the VAA Version + - `guardian_set_index` ++"u32"++ - indicates which Guardian set is signing + - `len_signatures` ++"u8"++ - the number of signatures stored + - `signatures` ++"[]signature"++ - the collection of Guardian signatures - The address of the `HubGovernor` contract on Ethereum Mainnet. + Where each `signature` is: - --- + - `index` ++"u8"++ - the index of this Guardian in the Guardian set + - `signature` ++"[65]byte"++ - the ECDSA signature - `targets` ++"address[]"++ +- **Body** - _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body to maintain a one-to-one relationship between VAAs and messages to avoid double-processing messages + - `timestamp` ++"u32"++ - the timestamp of the block this message was published in + - `nonce` ++"u32"++ + - `emitter_chain` ++"u16"++ - the id of the chain that emitted the message + - `emitter_address` ++"[32]byte"++ - the contract address (Wormhole formatted) that called the Core Contract + - `sequence` ++"u64"++ - the auto-incrementing integer that represents the number of messages published by this emitter + - `consistency_level` ++"u8"++ - the consistency level (finality) required by this emitter + - `payload` ++"[]byte"++ - arbitrary bytes containing the data to be acted on - An array that specifies the addresses that will receive the proposal's actions. Here, both are set to the `HUB_MESSAGE_DISPATCHER_ADDRESS`. +The deterministic nature of the body is only strictly true once the chain's state is finalized. If a reorg occurs, and a transaction that previously appeared in block X is replaced by block Y, Guardians observing different forks may generate different VAAs for what the emitter contract believes is the same message. This scenario is less likely once a block is sufficiently buried, but it can still happen if you choose a faster (less finalized) consistency level - --- +The body contains relevant information for entities, such as contracts or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract. - `values` ++"uint256[]"++ +Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify VAAs as authentic. If a VAA has a specific destination, relayers are responsible for appropriately completing that delivery. - An array containing the value of each transaction (in Wei). In this case, both are set to zero because no ETH is being transferred. +## Consistency and Finality - --- +The consistency level determines whether Guardians wait for a chain's final commitment state or issue a VAA sooner under less-final conditions. This choice is especially relevant for blockchains without instant finality, where the risk of reorganization remains until a block is deeply confirmed. - `calldatas` ++"bytes[]"++ +Guardian watchers are specialized processes that monitor each blockchain in real-time. They enforce the selected consistency level by deciding whether enough commitment has been reached before signing and emitting a VAA. Some chains allow only one commitment level (effectively final), while others let integrators pick between near-final or fully finalized states. Choosing a faster option speeds up VAA production but increases reorg risk. A more conservative option takes longer but reduces the likelihood of rollback. - The calldata for the proposal. These are encoded contract calls containing cross-chain dispatch instructions for minting tokens and sending ETH. The calldata specifies minting 10 W tokens to the Optimism treasury and sending 15 ETH to the Arbitrum treasury. +## Signatures - --- +The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. - `description` ++"string"++ +```js +// hash the bytes of the body twice +digest = keccak256(keccak256(body)) +// sign the result +signature = ecdsa_sign(digest, key) +``` - A description of the proposal, outlining the intent to mint tokens to Optimism and send ETH to Arbitrum. +!!!tip "Hash vs. double hash" + Different implementations of the ECDSA signature validation may apply a keccak256 hash to the message passed, so care must be taken to pass the correct arguments. + + For example, the [Solana secp256k1 program](https://docs.solanalabs.com/runtime/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -??? interface "Returns" +## Payload Types - `proposalId` ++"uint256"++ +Different applications built on Wormhole may specify a format for the payloads attached to a VAA. This payload provides information on the target chain and contract so it can take action (e.g., minting tokens to a receiver address). - The ID of the newly created proposal on the hub chain. +### Token Transfer -## Vote on the Proposal via Spoke +Many bridges use a lockup/mint and burn/unlock mechanism to transfer tokens between chains. Wormhole's generic message-passing protocol handles the routing of lock and burn events across chains to ensure Wormhole's Token Bridge is chain-agnostic and can be rapidly integrated into any network with a Wormhole contract. -Once the proposal is created on the hub chain, stakeholders can cast their votes on the spoke chains. This snippet demonstrates how to connect to a spoke chain and cast a vote for the proposal. The voting power (weight) is calculated based on each stakeholder's token holdings on the spoke chain. +Transferring tokens from the sending chain to the destination chain requires the following steps: -Key actions: +1. Lock the token on the sending chain +2. The sending chain emits a message as proof the token lockup is complete +3. The destination chain receives the message confirming the lockup event on the sending chain +4. The token is minted on the destination chain -- Connect to the `SpokeVoteAggregator` contract on the spoke chain. This contract aggregates votes from the spoke chains and relays them to the hub chain -- Cast a vote in support of the proposal +The message the sending chain emits to verify the lockup is referred to as a transfer message and has the following structure: -```solidity -// Connect to the SpokeVoteAggregator contract of the desired chain -SpokeVoteAggregator voteAggregator = SpokeVoteAggregator(VOTE_AGGREGATOR_ADDRESS); -// Cast a vote -uint8 support = 1; // 1 for supporting, 0 for opposing -uint256 weight = voteAggregator.castVote(proposalId, support); -``` +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `1` for a token transfer +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `fee` ++"u256"++ - portion of amount paid to a relayer -??? interface "Parameters" +This structure contains everything the destination chain needs to learn about a lockup event. Once the destination chain receives this payload, it can mint the corresponding asset. - `VOTE_AGGREGATOR_ADDRESS` ++"address"++ +Note that the destination chain is agnostic regarding how the tokens on the sending side were locked. They could have been burned by a mint or locked in a custody account. The protocol relays the event once enough Guardians have attested to its existence. - The address of the `SpokeVoteAggregator` contract on the spoke chain (Optimism or Arbitrum). +### Attestation - --- +While the destination chain can trust the message from the sending chain to inform it of token lockup events, it has no way of verifying the correct token is locked up. To solve this, the Token Bridge supports token attestation. - `proposalId` ++"uint256"++ +To create a token attestation, the sending chain emits a message containing metadata about a token, which the destination chain may use to preserve the name, symbol, and decimal precision of a token address. - The ID of the proposal created on the hub chain, which is being voted on. +The message format for token attestation is as follows: - --- +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `2` for an attestation +- `token_address` ++"[32]byte"++ - address of the originating token contract +- `token_chain` ++"u16"++ - chain ID of the originating token +- `decimals` ++"u8"++ - number of decimals this token should have +- `symbol` ++"[32]byte"++ - short name of asset +- `name` ++"[32]byte"++ - full name of asset - `support` ++"uint8"++ +#### Attestation Tips - The vote being cast (`1` for supporting the proposal, `0` for opposing). +Be aware of the following considerations when working with attestations: -??? interface "Returns" +- Attestations use a fixed-length byte array to encode UTF8 token name and symbol data. Because the byte array is fixed length, the data contained may truncate multibyte Unicode characters - `weight` ++"uint256"++ +- When sending an attestation VAA, it is recommended to send the longest UTF8 prefix that doesn't truncate a character and then right-pad it with zero bytes - The weight of the vote, determined by the voter’s token holdings on the spoke chain. +- When parsing an attestation VAA, it is recommended to trim all trailing zero bytes and convert the remainder to UTF-8 via any lossy algorithm -## Vote Aggregation +- Be mindful that different on-chain systems may have different VAA parsers, resulting in different names/symbols on different chains if the string is long or contains invalid UTF8 -In the background process, votes cast on the spoke chains are aggregated and sent back to the hub chain for final tallying. This is typically handled off-chain by a "crank turner" service, which periodically queries the vote status and updates the hub chain. +- Without knowing a token's decimal precision, the destination chain cannot correctly mint the number of tokens when processing a transfer. For this reason, the Token Bridge requires an attestation for each token transfer -Key actions: +### Token Transfer with Message -- Aggregate votes from different chains and submit them to the hub chain for tallying +The Token Transfer with Message data structure is identical to the token-only data structure, except for the following: -```solidity -// Aggregate votes sent to Hub (this would typically be done by a "crank turner" off-chain) -hubVotePool.crossChainVote(queryResponseRaw, signatures); -``` +- **`fee` field** - replaced with the `from_address` field +- **`payload` field** - is added containing arbitrary bytes. A dApp may include additional data in this arbitrary byte field to inform some application-specific behavior -??? interface "Parameters" +This VAA type was previously known as Contract Controlled Transfer and is also sometimes referred to as a `payload3` message. The Token Transfer with Message data sructure is as follows: - `queryResponseRaw` ++"bytes"++ +- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message +- `amount` ++"u256"++ - amount of tokens being transferred +- `token_address` ++"u8[32]"++ - address on the source chain +- `token_chain` ++"u16"++ - numeric ID for the source chain +- `to` ++"u8[32]"++ - address on the destination chain +- `to_chain` ++"u16"++ - numeric ID for the destination chain +- `from_address` ++"u8[32]"++ - address that called the Token Bridge on the source chain +- `payload` ++"[]byte"++ - message, arbitrary bytes, app-specific - The raw vote data from the spoke chains. +### Governance - --- +Governance VAAs don't have a `payload_id` field like the preceding formats. Instead, they trigger an action in the deployed contracts (for example, an upgrade). - `signatures` ++"bytes"++ +#### Action Structure - Cryptographic signatures that verify the validity of the votes from the spoke chains. +Governance messages contain pre-defined actions, which can target the various Wormhole modules currently deployed on-chain. The structure includes the following fields: -## Execute Proposal and Dispatch Cross-Chain Messages +- `module` ++"u8[32]"++ - contains a right-aligned module identifier +- `action` ++"u8"++ - predefined governance action to execute +- `chain` ++"u16"++ - chain the action is targeting. This should be set to `0` for all chains +- `args` ++"any"++ - arguments to the action -After the proposal passes and the votes are tallied, the next step is to execute the proposal. The `HubGovernor` contract will dispatch the cross-chain messages to the spoke chains, where the respective treasuries will receive the tokens. +Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. -Key actions: +```js +module: 0x0000000000000000000000000000000000000000000000000000436f7265 +action: 1 +chain: 1 +new_contract: 0x348567293758957162374959376192374884562522281937446234828323 +``` -- Execute the proposal after the voting period ends and the proposal passes -- The `execute` function finalizes the proposal execution by dispatching the cross-chain governance actions. The `descriptionHash` ensures that the executed proposal matches the one that was voted on. +#### Actions -```solidity -HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS); -// Standard timelock execution -governor.execute(targets, values, calldatas, descriptionHash); -``` +The meaning of each numeric action is pre-defined and documented in the Wormhole design documents. For each application, the relevant definitions can be found via these links: -??? interface "Parameters" +- [Core governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0002_governance_messaging.md){target=\_blank} +- [Token Bridge governance actions](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md){target=\_blank} - `governor` ++"HubGovernor"++ +## Lifetime of a Message - The `HubGovernor` contract instance. +Anyone can submit a VAA to the target chain. Guardians typically don't perform this step to avoid transaction fees. Instead, applications built on top of Wormhole can acquire a VAA via the Guardian RPC and submit it in a separate flow. - --- +With the concepts now defined, it is possible to illustrate a full flow for message passing between two chains. The following stages demonstrate each step of processing that the Wormhole network performs to route a message. - `targets` ++"address[]"++ +1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians +2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA +3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step - An array containing the target addresses for the proposal’s transactions (in this case, the `HUB_MESSAGE_DISPATCHER_ADDRESS` for both). +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) - --- +## Next Steps - `values` ++"uint256[]"++ +
- An array of values (in Wei) associated with each transaction (both are zero in this case). +- :octicons-book-16:{ .lg .middle } **Guardians** --- - `calldatas` ++"bytes[]"++ - - The encoded transaction data to dispatch the governance actions (e.g., minting tokens and transferring ETH). + Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. - --- + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) - `descriptionHash` ++"bytes32"++ +- :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** - A hash of the proposal’s description, used to verify the proposal before execution. + --- -??? interface "Returns" + Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. - No direct return, but executing this function finalizes the cross-chain governance actions by dispatching the encoded messages via Wormhole to the spoke chains. + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) -Once the proposal is executed, the encoded messages will be dispatched via Wormhole to the spoke chains, where the Optimism and Arbitrum treasuries will receive their respective funds. +
--- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/settlement/.index/ +Doc-Content: https://wormhole.com/docs/protocol/introduction/ --- BEGIN CONTENT --- --- -title: Wormhole Settlement -description: Follow step-by-step tutorials to integrate Wormhole Settlement Routes using the SDK for seamless cross-chain swaps and efficient asset transfers. +title: Introduction to Wormhole +description: Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +categories: Basics --- -# Wormhole Settlement +# Introduction to Wormhole -This section provides hands-on tutorials to help you integrate Wormhole Settlement Routes into your application. Learn how to use the SDK to manage cross-chain swaps, optimize fees, and streamline transaction execution. +In the rapidly evolving landscape of blockchain technology, interoperability between different blockchains remains a significant challenge. Developers often face hurdles in creating applications that can seamlessly operate across multiple blockchains, limiting innovation and the potential of decentralized ecosystems. -## Tutorials +Wormhole addresses this problem by providing a _generic message-passing_ protocol that enables secure and efficient communication between blockchains. By allowing data and asset transfers across various blockchain networks, Wormhole breaks down the walls that traditionally separate these ecosystems. -
+Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -- :octicons-repo-16:{ .lg .middle } **Integrate Wormhole Settlement Routes using the SDK** +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) - --- +!!! note + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. - Learn how to integrate Wormhole Settlement Routes using the SDK to simplify cross-chain swaps, manage fees, and execute seamless transactions. +Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. - [:custom-arrow: Integrate Settlement Routes](/docs/tutorials/settlement/settlement-routes/) +This page introduces the key concepts and components necessary to understand how Wormhole enables fast, secure, and scalable cross-chain communication. -
---- END CONTENT --- +## What Problems Does Wormhole Solve? -Doc-Content: https://wormhole.com/docs/tutorials/settlement/.settlement-routes/ ---- BEGIN CONTENT --- ---- -title: Wormhole Settlements -description: Learn how to integrate Wormhole Settlement Routes using the SDK to simplify cross-chain swaps, manage fees, and execute seamless transactions. ---- +Interoperability is a critical challenge in the rapidly evolving blockchain landscape. Individual blockchains are often isolated, limiting the potential for integrated applications operating across multiple ecosystems. Wormhole solves this problem by enabling seamless communication between blockchains, allowing developers to create multichain applications that can leverage the unique features of each network. -# Integrate Wormhole Settlement Routes Using the SDK +Critical problems Wormhole addresses include: -## Introduction +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. -This guide explains integrating Wormhole Settlement Routes from the Wormhole SDK into your application. These Routes abstract the complexity of cross-chain token swaps by handling route discovery, fee estimation, and transaction construction, all useful for dApps seeking to embed cross-chain swaps. By following this tutorial you will install the Wormhole SDK Route package, configure and execute a swap, and explore error handling and troubleshooting. +## What Does Wormhole Offer? -## Prerequisites +Wormhole provides a suite of tools and protocols that support a wide range of use cases: -Before beginning this project, make sure you have the following: +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. -- **Wormhole SDK Route package** - installed using your preferred package manager +## What Isn't Wormhole? - To install the package with npm, run the following command in your terminal: +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. - ```sh - npm install @mayan-finance/wormhole-sdk-route - ``` +## Use Cases of Wormhole - Alternatively, clone the repository and install dependencies: +Consider the following examples of potential applications enabled by Wormhole: - ```sh - git clone https://github.com/mayan-finance/wormhole-sdk-route.git - cd wormhole-sdk-route - npm install - ``` +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. -- **Data for parameters** - you will need: - - - [Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} for the source and destination chains - - An contract address for the token you want to swap and the token you want to receive on the destination chain +## Explore -## Configure and Setup +Discover more about the Wormhole ecosystem, components, and protocols: -To initiate a swap, you must create a configuration object that specifies all required parameters. These typically include: +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. -- `sourceChain` - identifier for the chain where the swap begins -- `destinationChain` - identifier for the target chain -- `inputTokenAddress` - address of the token you want to swap -- `outputTokenAddress` - identifier/address of the desired token on the destination chain -- `amount` - the amount to swap (expressed in the smallest unit, e.g., wei for Ethereum) -- `slippageTolerance` - acceptable percentage of slippage (e.g., 0.005 for 0.5%) +## Demos -```ts -import { SwapRoute, SwapRouteConfig } from '@mayan-finance/wormhole-sdk-route'; - -const config: SwapRouteConfig = { - sourceChain: 'ethereum', - destinationChain: 'solana', - inputTokenAddress: '0xYourInputTokenAddress', - outputTokenAddress: 'So11111111111111111111111111111111111111112', // Example token on Solana - amount: '1000000000000000000', // For instance, 1 token in wei - slippageTolerance: 0.005, // 0.5% slippage tolerance - // Additional parameters may be included as needed -}; +Demos offer more realistic implementations than tutorials: -const swapRoute = new SwapRoute(config); -``` +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains. -## Execute a Swap + -### Fetch the Swap Route +!!! note + Wormhole Integration Complete? -Before sending a transaction, fetch the optimal swap route to review details such as fees and expected outputs: + Let us know so we can list your project in our ecosystem directory and introduce you to our global, multichain community! -```ts -async function getSwapDetails() { - try { - const routeDetails = await swapRoute.getRoute(); - console.log('Optimal Swap Route:', routeDetails); - return routeDetails; - } catch (error) { - console.error('Error fetching swap route:', error); - throw error; - } -} + **[Reach out now!](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}** -getSwapDetails(); -``` - -### Execute the Swap Transaction - -Once the route is confirmed, execute the swap: - -```ts -async function executeSwap() { - try { - const txResponse = await swapRoute.executeSwap(); - console.log('Swap executed successfully:', txResponse); - // Further transaction handling (e.g., waiting for confirmation) can be added here. - } catch (error) { - console.error('Swap execution failed:', error); - } -} - -executeSwap(); -``` - -## Complete Example Integration - -Below is a complete example that puts together configuration, route fetching, and swap execution: - -```ts -import { SwapRoute, SwapRouteConfig } from '@mayan-finance/wormhole-sdk-route'; - -async function performSwap() { - // Configure the swap parameters - const config: SwapRouteConfig = { - sourceChain: 'ethereum', - destinationChain: 'solana', - inputTokenAddress: '0xYourInputTokenAddress', - outputTokenAddress: 'So11111111111111111111111111111111111111112', - amount: '1000000000000000000', - slippageTolerance: 0.005, - // Include additional settings as needed - }; +## Supported Networks by Product - // Initialize the swap route - const swapRoute = new SwapRoute(config); - - try { - // Retrieve the optimal swap route details - const routeDetails = await swapRoute.getRoute(); - console.log('Optimal Swap Route:', routeDetails); - - // Execute the swap transaction - const txResponse = await swapRoute.executeSwap(); - console.log('Swap Transaction Response:', txResponse); - } catch (error) { - console.error('An error occurred during the swap process:', error); - } -} - -performSwap(); -``` - -## Error Handling and Troubleshooting - -- **Route fetching errors** - ensure all configuration parameters (chain IDs, token addresses, amounts) are correct and that network endpoints are reachable -- **Transaction execution errors** - verify that the connected wallet has sufficient funds and that transaction parameters meet the network’s requirements. Detailed logging can assist with troubleshooting -- **Miscellaneous** - to pass a `ReferrerAddress` to the initiation functions, you can create a class that extends the `MayanRoute` class. Override the `referrerAddress` method to return addresses by platform, as shown in this example: - - ```ts - class MayanRefRoute extends MayanRoute { - override referrerAddress(): ReferrerAddresses | undefined { - return { evm: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbe" }; - } - } - ``` +Wormhole supports a growing number of blockchains. Check out the [Supported Networks by Product](/docs/products/reference/supported-networks/){target=\_blank} page to see which networks are supported for each Wormhole product. --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/solidity-sdk/cross-chain-contracts/ +Doc-Content: https://wormhole.com/docs/protocol/security/ --- BEGIN CONTENT --- --- -title: Create Cross-Chain Contracts -description: Learn how to create cross-chain contracts using Wormhole's Solidity SDK. Deploy contracts on Avalanche and Celo Testnets and send messages across chains. +title: Security +description: Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +categories: Basics --- -# Create Cross-Chain Messaging Contracts +# Security -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-wormhole-messaging){target=\_blank} +## Core Security Assumptions -## Introduction +At its core, Wormhole is secured by a network of [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} nodes that validate and sign messages. If a super majority (e.g., 13 out of 19) of Guardians sign the same message, it can be considered valid. A smart contract on the target chain will verify the signatures and format of the message before approving any transaction. -Wormhole's cross-chain messaging allows smart contracts to interact seamlessly across multiple blockchains. This enables developers to build decentralized applications that leverage the strengths of different networks, whether it's Avalanche, Celo, Ethereum, or beyond. In this tutorial, we'll explore using [Wormhole's Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} to create cross-chain contracts to send and receive messages across chains. +- Wormhole's core security primitive is its signed messages (signed [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}) +- The Guardian network is currently secured by a collection of 19 of the world's top [validator companies](https://wormhole-foundation.github.io/wormhole-dashboard/#/?endpoint=Mainnet){target=\_blank} +- Guardians produce signed state attestations (signed VAAs) when requested by a Core Contract integrator +- Every Guardian runs full nodes (rather than light nodes) of every blockchain in the Wormhole network, so if a blockchain suffers a consensus attack or hard fork, the blockchain will disconnect from the network rather than potentially produce invalid signed VAAs +- Any Signed VAA can be verified as authentic by the Core Contract of any other chain +- [Relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} are considered untrusted in the Wormhole ecosystem -Wormhole's messaging infrastructure simplifies data transmission, event triggering, and transaction initiation across blockchains. In this tutorial, we'll guide you through a simple yet powerful hands-on demonstration that showcases this practical capability. We'll deploy contracts on two Testnets—Avalanche Fuji and Celo Alfajores—and send messages from one chain to another. This tutorial is perfect for those new to cross-chain development and seeking hands-on experience with Wormhole's powerful toolkit. +In summary: -By the end of this tutorial, you will have not only built a fully functioning cross-chain message sender and receiver using Solidity but also developed a comprehensive understanding of how to interact with the Wormhole relayer, manage cross-chain costs, and ensure your smart contracts are configured correctly on both source and target chains. +- **Core integrators aren't exposed to risk from chains and contracts they don't integrate with** +- By default, you only trust Wormhole's signing process and the core contracts of the chains you're on +- You can expand your contract and chain dependencies as you see fit -This tutorial assumes a basic understanding of Solidity and smart contract development. Before diving in, it may be helpful to review [the basics of Wormhole](/docs/learn/){target=\_blank} to familiarize yourself with the protocol. +Core assumptions aside, many other factors impact the real-world security of decentralized platforms. Here is more information on additional measures that have been put in place to ensure the security of Wormhole. -## Wormhole Overview +## Guardian Network -We'll interact with two key Wormhole components: the [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} and the [Wormhole Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank}. The relayer handles cross-chain message delivery and ensures the message is accurately received on the target chain. This allows smart contracts to communicate across blockchains without developers worrying about the underlying complexity. +Wormhole is an evolving platform. While the Guardian set currently comprises 19 validators, this is a limitation of current blockchain technology. -Additionally, we'll rely on the Wormhole relayer to automatically determine cross-chain transaction costs and facilitate payments. This feature simplifies cross-chain development by allowing you to specify only the target chain and the message. The relayer handles the rest, ensuring that the message is transmitted with the appropriate fee. +### Governance -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +Governance is the process through which contract upgrades happen. Guardians manually vote on governance proposals that originate inside the Guardian Network and are then submitted to ecosystem contracts. -## Prerequisites +This means that governance actions are held to the same security standard as the rest of the system. A two-thirds supermajority of the Guardians is required to pass any governance action. -Before starting this tutorial, ensure you have the following: +Governance messages can target any of the various wormhole modules, including the core contracts and all currently deployed token bridge contracts. When a Guardian signs such a message, its signature implies a vote on the action in question. Once more than two-thirds of the Guardians have signed, the message and governance action are considered valid. -- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine -- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for deploying contracts -- Testnet tokens for [Avalanche-Fuji](https://core.app/tools/testnet-faucet/?token=C){target=\_blank} and [Celo-Alfajores](https://faucet.celo.org/alfajores){target=\_blank} to cover gas fees -- Wallet private key +All governance actions and contract upgrades have been managed via Wormhole's on-chain governance system. -## Build Cross-Chain Messaging Contracts +Via governance, the Guardians can: -In this section, we'll deploy two smart contracts: one to send a message from Avalanche Fuji and another to receive it on Celo Alfajores. The contracts interact with the Wormhole relayer to transmit messages across chains. +- Change the current Guardian set +- Expand the Guardian set +- Upgrade ecosystem contract implementations -At a high level, our contracts will: +The governance system is fully open source in the core repository. See the [Open Source section](#open-source){target=\_blank} for contract source. -1. Send a message from Avalanche to Celo using the Wormhole relayer -2. Receive and process the message on Celo, logging the content of the message +## Monitoring -Before diving into the deployment steps, let's first break down key parts of the contracts. +A key element of Wormhole's defense-in-depth strategy is that each Guardian is a highly competent validator company with its own in-house processes for running, monitoring, and securing blockchain operations. This heterogeneous approach to monitoring increases the likelihood that fraudulent activity is detected and reduces the number of single failure points in the system. -### Sender Contract: MessageSender +Guardians are not just running Wormhole validators; they're running validators for every blockchain inside of Wormhole as well, which allows them to perform monitoring holistically across decentralized computing rather than just at a few single points. -The `MessageSender` contract is responsible for quoting the cost of sending a message cross-chain and then sending that message. +Guardians monitor: -Key functions include: +- Block production and consensus of each blockchain - if a blockchain's consensus is violated, it will be disconnected from the network until the Guardians resolve the issue +- Smart contract level data - via processes like the Governor, Guardians constantly monitor the circulating supply and token movements across all supported blockchains +- Guardian level activity - the Guardian Network functions as an autonomous decentralized computing network, ensuring independent security measures across its validators - - **`quoteCrossChainCost`** - calculates the cost of delivering a message to the target chain using the Wormhole relayer - - **`sendMessage`** - encodes the message and sends it to the target chain and contract address using the Wormhole relayer +## Asset Layer Protections -Here's the core of the contract: +One key strength of the Wormhole ecosystem is the Guardians’ ability to validate and protect the integrity of assets across multiple blockchains. -```solidity -uint16 targetChain, - address targetAddress, - string memory message - ) external payable { - uint256 cost = quoteCrossChainCost(targetChain); +To enforce the Wormhole Asset Layer’s core protections, the Global Accountant tracks the total circulating supply of all Wormhole assets across all chains, preventing any blockchain from bridging assets that could violate the supply invariant. - require( - msg.value >= cost, - "Insufficient funds for cross-chain delivery" - ); +In addition to the Global Accountant, Guardians may only sign transfers that do not violate the requirements of the Governor. The [Governor](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0007_governor.md){target=\_blank} tracks inflows and outflows of all blockchains and delays suspicious transfers that may indicate an exploit. - wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(message, msg.sender), - 0, - GAS_LIMIT - ); - } -``` +## Open Source -You can find the full code for the `MessageSender.sol` below. +Wormhole builds in the open and is always open source. -??? code "MessageSender.sol" +- **[Wormhole core repository](https://github.com/wormhole-foundation/wormhole){target=\_blank}** +- **[Wormhole Foundation GitHub organization](https://github.com/wormhole-foundation){target=\_blank}** +- **[Wormhole contract deployments](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - ```solidity - // SPDX-License-Identifier: MIT -pragma solidity ^0.8.18; +## Audits -import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeRelayer.sol"; +Wormhole has been heavily audited, with _29 third-party audits completed_ and more started. Audits have been performed by the following firms: -contract MessageSender { - IWormholeRelayer public wormholeRelayer; - uint256 constant GAS_LIMIT = 50000; +- [Trail of Bits](https://www.trailofbits.com/){target=\_blank} +- [Neodyme](https://neodyme.io/en/){target=\_blank} +- [Kudelski](https://kudelskisecurity.com/){target=\_blank} +- [OtterSec](https://osec.io/){target=\_blank} +- [Certik](https://www.certik.com/){target=\_blank} +- [Hacken](https://hacken.io/){target=\_blank} +- [Zellic](https://www.zellic.io/){target=\_blank} +- [Coinspect](https://www.coinspect.com/){target=\_blank} +- [Halborn](https://www.halborn.com/){target=\_blank} +- [Cantina](https://cantina.xyz/welcome){target=\_blank} - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - } +All audits and final reports can be found in [security page of the GitHub Repo](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#3rd-party-security-audits){target=\blank}. - function quoteCrossChainCost( - uint16 targetChain - ) public view returns (uint256 cost) { - (cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - 0, - GAS_LIMIT - ); - } +## Bug Bounties - function sendMessage( - uint16 targetChain, - address targetAddress, - string memory message - ) external payable { - uint256 cost = quoteCrossChainCost(targetChain); +Wormhole has one of the largest bug bounty programs in software development and has repeatedly shown commitment to engaging with the white hat community. - require( - msg.value >= cost, - "Insufficient funds for cross-chain delivery" - ); +Wormhole runs a bug bounty program through [Immunefi](https://immunefi.com/bug-bounty/wormhole/){target=\blank} program, with a top payout of **5 million dollars**. - wormholeRelayer.sendPayloadToEvm{value: cost}( - targetChain, - targetAddress, - abi.encode(message, msg.sender), - 0, - GAS_LIMIT - ); - } -} - ``` +If you are interested in contributing to Wormhole security, please look at this section for [Getting Started as a White Hat](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md#white-hat-hacking){target=\blank}, and follow the [Wormhole Contributor Guidelines](https://github.com/wormhole-foundation/wormhole/blob/main/CONTRIBUTING.md){target=\blank}. -### Receiver Contract: MessageReceiver +For more information about submitting to the bug bounty programs, refer to the [Wormhole Immunefi page](https://immunefi.com/bug-bounty/wormhole/){target=\blank}. -The `MessageReceiver` contract handles incoming cross-chain messages. When a message arrives, it decodes the payload and logs the message content. It ensures that only authorized contracts can send and process messages, adding an extra layer of security in cross-chain communication. +## Learn More -#### Emitter Validation and Registration +The [SECURITY.md](https://github.com/wormhole-foundation/wormhole/blob/main/SECURITY.md){target=\blank} from the official repository has the latest security policies and updates. +--- END CONTENT --- -In cross-chain messaging, validating the sender is essential to prevent unauthorized contracts from sending messages. The `isRegisteredSender` modifier ensures that messages can only be processed if they come from the registered contract on the source chain. This guards against malicious messages and enhances security. +Doc-Content: https://wormhole.com/docs/tools/cli/get-started/ +--- BEGIN CONTENT --- +--- +title: Wormhole CLI +description: Learn how to install and use the Wormhole CLI, including commands and examples for managing multichain deployments, generating VAAs, and querying contract info. +categories: Solidity-SDK, Typescript-SDK +--- -Key implementation details include: +# Wormhole CLI - - **`registeredSender`** - stores the address of the registered sender contract - - **`setRegisteredSender`** - registers the sender's contract address on the source chain. It ensures that only registered contracts can send messages, preventing unauthorized senders - - **`isRegisteredSender`** - restricts the processing of messages to only those from registered senders, preventing unauthorized cross-chain communication +This tool is a command-line interface to Wormhole, allowing you to perform various actions, such as querying a transaction's status or submitting token transfers. -```solidity +## Installation -require( - registeredSenders[sourceChain] == sourceAddress, - "Not registered sender" - ); - _; - } +Clone the repository and change directories to the appropriate directory: - function setRegisteredSender( - uint16 sourceChain, - bytes32 sourceAddress - ) public { - require( - msg.sender == registrationOwner, - "Not allowed to set registered sender" - ); - registeredSenders[sourceChain] = sourceAddress; - } +```bash +git clone https://github.com/wormhole-foundation/wormhole && +cd wormhole/clients/js ``` -#### Message Processing - -The `receiveWormholeMessages` is the core function that processes the received message. It checks that the Wormhole relayer sent the message, decodes the payload, and emits an event with the message content. It is essential to verify the message sender to prevent unauthorized messages. - -```solidity -bytes memory payload, - bytes[] memory, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 - ) public payable override isRegisteredSender(sourceChain, sourceAddress) { - require( - msg.sender == address(wormholeRelayer), - "Only the Wormhole relayer can call this function" - ); - - // Decode the payload to extract the message - string memory message = abi.decode(payload, (string)); - - // Example use of sourceChain for logging - if (sourceChain != 0) { - emit SourceChainLogged(sourceChain); - } +Build and install the CLI tool: - // Emit an event with the received message - emit MessageReceived(message); - } +```bash +make install ``` -You can find the full code for the `MessageReceiver.sol` below. +This installs two binaries, `worm-fetch-governance` and `worm` on your `$PATH`. To use `worm`, set up `$HOME/.wormhole/.env` with your private keys, based on `.env.sample` in this folder. -??? code "MessageReceiver.sol" +## Usage - ```solidity - // SPDX-License-Identifier: MIT -pragma solidity ^0.8.18; +You can interact with the Wormhole CLI by typing `worm` and including the `command` and any necessary subcommands and parameters. -import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeRelayer.sol"; -import "lib/wormhole-solidity-sdk/src/interfaces/IWormholeReceiver.sol"; - -contract MessageReceiver is IWormholeReceiver { - IWormholeRelayer public wormholeRelayer; - address public registrationOwner; - - // Mapping to store registered senders for each chain - mapping(uint16 => bytes32) public registeredSenders; - - event MessageReceived(string message); - event SourceChainLogged(uint16 sourceChain); - - constructor(address _wormholeRelayer) { - wormholeRelayer = IWormholeRelayer(_wormholeRelayer); - registrationOwner = msg.sender; // Set contract deployer as the owner - } +| Command | Description | +|--------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| +| `worm aptos INSERT_COMMAND` | Aptos utilities | +| `worm edit-vaa INSERT_COMMAND` | Edits or generates a VAA | +| `worm evm INSERT_COMMAND` | EVM utilities | +| `worm generate INSERT_COMMAND` | Generate VAAs (Devnet and Testnet only) | +| `worm info INSERT_COMMAND` | Contract, chain, RPC, and address information utilities | +| `worm near INSERT_NETWORK, INSERT_ACCOUNT` | NEAR utilities | +| `worm parse INSERT_VAA` | Parse a VAA (can be in either hex or base64 format) | +| `worm recover INSERT_DIGEST INSERT_SIGNATURE` | Recover an address from a signature | +| `worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH` | Prints information about the automatic delivery initiated on the specified network, chain, and transaction hash | +| `worm submit INSERT_VAA` | Execute a VAA | +| `worm sui INSERT_COMMAND` | Sui utilities | +| `worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK` | Transfers a token | +| `worm verify-vaa INSERT_VAA, INSERT_NETWORK` | Verifies a VAA by querying the Core Contract on Ethereum | - modifier isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress) { - require( - registeredSenders[sourceChain] == sourceAddress, - "Not registered sender" - ); - _; - } +You can also refer to the below options, available with all `worm` commands: - function setRegisteredSender( - uint16 sourceChain, - bytes32 sourceAddress - ) public { - require( - msg.sender == registrationOwner, - "Not allowed to set registered sender" - ); - registeredSenders[sourceChain] = sourceAddress; - } +```bash +Options: + --help Show help [boolean] + --version Show version number [boolean] +``` - // Update receiveWormholeMessages to include the source address check - function receiveWormholeMessages( - bytes memory payload, - bytes[] memory, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 - ) public payable override isRegisteredSender(sourceChain, sourceAddress) { - require( - msg.sender == address(wormholeRelayer), - "Only the Wormhole relayer can call this function" - ); +### Subcommands - // Decode the payload to extract the message - string memory message = abi.decode(payload, (string)); +??? interface "Aptos" + ```bash + worm aptos INSERT_COMMAND - // Example use of sourceChain for logging - if (sourceChain != 0) { - emit SourceChainLogged(sourceChain); - } +Commands: + worm aptos init-token-bridge Init token bridge contract + worm aptos init-wormhole Init Wormhole core contract + worm aptos deploy Deploy an Aptos package + worm aptos deploy-resource Deploy an Aptos package using a + resource account + worm aptos send-example-message Send example message + + worm aptos derive-resource-account Derive resource account address + + worm aptos derive-wrapped-address Derive wrapped coin type + + worm aptos hash-contracts Hash contract bytecodes for upgrade + worm aptos upgrade Perform upgrade after VAA has been + submitted + worm aptos migrate Perform migration after contract + upgrade + worm aptos faucet Request money from the faucet for a + given account + worm aptos start-validator Start a local aptos validator - // Emit an event with the received message - emit MessageReceived(message); - } -} +Options: + --help Show help [boolean] + --version Show version number [boolean] ``` -## Deploy Contracts - -This section will guide you through deploying the cross-chain messaging contracts on the Avalanche Fuji and Celo Alfajores Testnets. Follow these steps to get your contracts up and running. +??? interface "Edit VAA" + ```bash + worm edit-vaa INSERT_COMMAND -### Deployment Tools -We use _Foundry_ to deploy our smart contracts. However, you can use any tool you're comfortable with, such as: +Options: + --help Show help [boolean] + --version Show version number [boolean] + -v, --vaa vaa in hex format [string] [required] + -n, --network Network + [required] [choices: "mainnet", "testnet", "devnet"] + --guardian-set-index, --gsi guardian set index [number] + --signatures, --sigs comma separated list of signatures [string] + --wormscanurl, --wsu url to wormscan entry for the vaa that + includes signatures [string] + --wormscan, --ws if specified, will query the wormscan entry + for the vaa to get the signatures [boolean] + --emitter-chain-id, --ec emitter chain id to be used in the vaa + [number] + --emitter-address, --ea emitter address to be used in the vaa[string] + --nonce, --no nonce to be used in the vaa [number] + --sequence, --seq sequence number to be used in the vaa[string] + --consistency-level, --cl consistency level to be used in the vaa + [number] + --timestamp, --ts timestamp to be used in the vaa in unix + seconds [number] + -p, --payload payload in hex format [string] + --guardian-secret, --gs Guardian's secret key [string] + ``` - - [Remix](https://remix.ethereum.org/){target=\_blank} for a browser-based IDE - - [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started#installation){target=\_blank} for a more extensive JavaScript/TypeScript workflow - - [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for a CLI-focused experience with built-in scripting and testing features +??? interface "EVM" + ```bash + worm evm INSERT_COMMAND -The contracts and deployment steps remain the same regardless of your preferred tool. The key is to ensure you have the necessary Testnet funds and are deploying to the right networks. +Commands: + worm evm address-from-secret Compute a 20 byte eth address from a 32 + byte private key + worm evm storage-update Update a storage slot on an EVM fork + during testing (anvil or hardhat) + worm evm chains Return all EVM chains + worm evm info Query info about the on-chain state of + the contract + worm evm hijack Override the guardian set of the core + bridge contract during testing (anvil + or hardhat) + worm evm start-validator Start a local EVM validator -### Repository Setup +Options: + --help Show help [boolean] + --version Show version number [boolean] + --rpc RPC endpoint [string] + ``` -To get started with cross-chain messaging using Wormhole, first clone the [GitHub repository](https://github.com/wormhole-foundation/demo-wormhole-messaging){target=\_blank}. This repository includes everything you need to deploy, interact, and test the message flow between chains. +??? interface "Generate" + ```bash + worm generate INSERT_COMMAND -This demo focuses on using the scripts, so it's best to take a look at them, starting with `deploySender.ts`, `deployReceiver.ts`, and `sendMessage.ts`. +Commands: + worm generate registration Generate registration VAA + worm generate upgrade Generate contract upgrade VAA + worm generate attestation Generate a token attestation VAA + worm generate recover-chain-id Generate a recover chain ID VAA + worm generate Sets the default delivery provider + set-default-delivery-provider for the Wormhole Relayer contract -To configure the dependencies properly, run the following command: +Options: + --help Show help [boolean] + --version Show version number [boolean] + -g, --guardian-secret Guardians' secret keys (CSV) [string] [required] + ``` -```bash -npm install -``` +??? interface "Info" + ```bash + worm info INSERT_COMMAND -The repository includes: +Commands: + worm info chain-id Print the wormhole chain ID integer + associated with the specified chain + name + worm info contract Print contract address + + worm info emitter
Print address in emitter address + format + worm info origin
Print the origin chain and address + of the asset that corresponds to the + given chain and address. + worm info registrations Print chain registrations + + worm info rpc Print RPC address + worm info wrapped Print the wrapped address on the + target chain that corresponds with + the specified origin chain and + address. -- Two Solidity contracts: +Options: + --help Show help [boolean] + --version Show version number [boolean]
+ ``` - - **`MessageSender.sol`** - contract that sends the cross-chain message from Avalanche - - **`MessageReceiver.sol`** - contract that receives the cross-chain message on Celo +??? interface "NEAR" + ```bash + worm near INSERT_COMMAND -- Deployment scripts located in the `script` directory: +Commands: + worm near contract-update Submit a contract update using our specific + APIs + worm near deploy Submit a contract update using near APIs - - **`deploySender.ts`** - deploys the `MessageSender` contract to Avalanche - - **`deployReceiver.ts`** - deploys the `MessageReceiver` contract to Celo - - **`sendMessage.ts`** - sends a message from Avalanche to Celo +Options: + --help Show help [boolean] + --version Show version number [boolean] + -m, --module Module to query [choices: "Core", "NFTBridge", "TokenBridge"] + -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] + --account Near deployment account [string] [required] + --attach Attach some near [string] + --target Near account to upgrade [string] + --mnemonic Near private keys [string] + --key Near private key [string] + -r, --rpc Override default rpc endpoint url [string] + ``` -- Configuration files and ABI JSON files for easy deployment and interaction: +??? interface "Parse" + ```bash + worm parse INSERT_VAA - - **`chains.json`** - configuration file that stores key information for the supported Testnets, including the Wormhole relayer addresses, RPC URLs, and chain IDs. You likely won't need to modify this file unless you're working with different networks +Positionals: + vaa vaa [string] - - A dedicated `interfaces` directory inside the `src` folder for TypeScript type definitions: +Options: + --help Show help [boolean] + --version Show version number [boolean] + ``` - - **`ChainsConfig.ts`** - defines the types for the `chains.json` configuration file - - **`DeployedContracts.ts`** - contains types for deployed contract addresses and related information - - **`MessageJsons.ts`** - includes types for ABI and bytecode JSONs used by the deployment scripts - - **`index.ts`** - serves as an export aggregator for the interfaces, simplifying imports in other files +??? interface "Recover" + ```bash + worm recover INSERT_DIGEST INSERT_SIGNATURE -### Important Setup Steps +Positionals: + digest digest [string] + signature signature [string] -1. **Add your private key** - create a `.env` file in the root of the project and add your private key: - - ```env - touch .env +Options: + --help Show help [boolean] + --version Show version number [boolean] ``` - Inside `.env`, add your private key in the following format: - - ```env - PRIVATE_KEY=INSERT_PRIVATE_KEY - ``` - -2. **Compile the contracts** - ensure everything is set up correctly by compiling the contracts: - +??? interface "Status" ```bash - forge build - ``` - -The expected output should be similar to this: - -
-forge build - > [⠒] Compiling... - > [⠰] Compiling 30 files with 0.8.23 - [⠔] Solc 0.8.23 finished in 2.29s -Compiler run successful! - -
- -### Deployment Process - -Both deployment scripts, `deploySender.ts` and `deployReceiver.ts`, perform the following key tasks: - -1. **Load configuration and contract details** - each script begins by loading the necessary configuration details, such as the network's RPC URL and the contract's ABI and bytecode. This information is essential for deploying the contract to the correct blockchain network - - === "`chains.json`" - - ```json - { - "chains": [ - { - "description": "Avalanche testnet fuji", - "chainId": 6, - "rpc": "https://api.avax-test.network/ext/bc/C/rpc", - "tokenBridge": "0x61E44E506Ca5659E6c0bba9b678586fA2d729756", - "wormholeRelayer": "0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB", - "wormhole": "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C" - }, - { - "description": "Celo Testnet", - "chainId": 14, - "rpc": "https://alfajores-forno.celo-testnet.org", - "tokenBridge": "0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153", - "wormholeRelayer": "0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84", - "wormhole": "0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56" - } - ] -} - ``` - - === "`deploySender.ts`" + worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH - ```typescript - const chains: ChainsConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); +Positionals: + network Network [choices: + 'mainnet', + 'testnet', + 'devnet'] + chain Source chain + [choices: + 'unset', + 'solana', + 'ethereum', + 'terra', + 'bsc', + 'polygon', + 'avalanche', + 'oasis', + 'algorand', + 'aurora', + 'fantom', + 'karura', + 'acala', + 'klaytn', + 'celo', + 'near', + 'moonbeam', + 'neon', + 'terra2', + 'injective', + 'osmosis', + 'sui', + 'aptos', + 'arbitrum', + 'optimism', + 'gnosis', + 'pythnet', + 'xpla', + 'btc', + 'base', + 'sei', + 'rootstock', + 'scroll', + 'mantle', + 'blast', + 'xlayer', + 'linea', + 'berachain', + 'seievm', + 'wormchain', + 'cosmoshub', + 'evmos', + 'kujira', + 'neutron', + 'celestia', + 'stargaze', + 'seda', + 'dymension', + 'provenance', + 'sepolia', + 'arbitrum_sepolia', + 'base_sepolia', + 'optimism_sepolia', + 'holesky', + 'polygon_sepolia'] + tx Source transaction hash [string] - // Get the Avalanche Fuji configuration - const avalancheChain = chains.chains.find((chain) => - chain.description.includes('Avalanche testnet') - ); - ``` +Options: + --help Show help [boolean] + --version Show version number [boolean] + ``` - === "`deployReceiver.ts`" +??? interface "Submit" + ```bash + worm submit INSERT_VAA - ```typescript - const chains: ChainsConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); +Positionals: + vaa vaa [string] - // Get the Celo Testnet configuration - const celoChain = chains.chains.find((chain) => - chain.description.includes('Celo Testnet') - ); - ``` +Options: + --help Show help [boolean] + --version Show version number [boolean] + -c, --chain chain name +[choices: 'unset', + 'solana', + 'ethereum', + 'terra', + 'bsc', + 'polygon', + 'avalanche', + 'oasis', + 'algorand', + 'aurora', + 'fantom', + 'karura', + 'acala', + 'klaytn', + 'celo', + 'near', + 'moonbeam', + 'neon', + 'terra2', + 'injective', + 'osmosis', + 'sui', + 'aptos', + 'arbitrum', + 'optimism', + 'gnosis', + 'pythnet', + 'xpla', + 'btc', + 'base', + 'sei', + 'rootstock', + 'scroll', + 'mantle', + 'blast', + 'xlayer', + 'linea', + 'berachain', + 'seievm', + 'wormchain', + 'cosmoshub', + 'evmos', + 'kujira', + 'neutron', + 'celestia', + 'stargaze', + 'seda', + 'dymension', + 'provenance', + 'sepolia', + 'arbitrum_sepolia', + 'base_sepolia', + 'optimism_sepolia', + 'holesky', + 'polygon_sepolia'] + -n, --network Network + [required] + [choices: + 'mainnet', + 'testnet', + 'devnet'] + -a, --contract-address Contract to submit VAA to (override config) [string] + --rpc RPC endpoint [string] + --all-chains, --ac Submit the VAA to all chains except for the origin + chain specified in the payload + [boolean] [default: false] + ``` - !!! note - The `chains.json` file contains the configuration details for the Avalanche Fuji and Celo Alfajores Testnets. You can modify this file to add more networks if needed. For a complete list of contract addresses, visit the [reference page](/docs/build/reference/){target=\_blank}. +??? interface "Sui" + ```bash + worm sui INSERT_COMMAND -2. **Set up provider and wallet** - the scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction +Commands: + worm sui build-coin Build wrapped coin and dump bytecode. - === "`deploySender.ts`" + Example: + worm sui build-coin -d 8 -v V__0_1_1 -n + testnet -r + "https://fullnode.testnet.sui.io:443" + worm sui deploy Deploy a Sui package + worm sui init-example-message-app Initialize example core message app + worm sui init-token-bridge Initialize token bridge contract + worm sui init-wormhole Initialize wormhole core contract + worm sui publish-example-message Publish message from example app via + core bridge + worm sui setup-devnet Setup devnet by deploying and + initializing core and token bridges and + submitting chain registrations. + worm sui objects Get owned objects by owner + worm sui package-id Get package ID from State object ID + worm sui tx Get transaction details - ```typescript - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - ``` +Options: + --help Show help [boolean] + --version Show version number [boolean] + ``` - === "`deployReceiver.ts`" +??? interface "Transfer" + ```bash + worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK - ```typescript - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - ``` - -3. **Deploy the contract** - the contract is deployed to the network specified in the configuration. Upon successful deployment, the contract address is returned, which is crucial for interacting with the contract later on - - === "`deploySender.ts`" - - ```typescript - avalancheChain.wormholeRelayer - ); - await senderContract.waitForDeployment(); - ``` - - === "`deployReceiver.ts`" - - ```typescript - celoChain.wormholeRelayer - ); - await receiverContract.waitForDeployment(); - ``` - -4. **Register the `MessageSender` on the target chain** - after you deploy the `MessageReceiver` contract on the Celo Alfajores network, the sender contract address from Avalanche Fuji needs to be registered. This ensures that only messages from the registered `MessageSender` contract are processed - - This additional step is essential to enforce emitter validation, preventing unauthorized senders from delivering messages to the `MessageReceiver` contract - - ```typescript - const avalancheSenderAddress = deployedContracts.avalanche?.MessageSender; - if (!avalancheSenderAddress) { - throw new Error('Avalanche MessageSender address not found.'); - } - - // Define the source chain ID for Avalanche Fuji - const sourceChainId = 6; - - // Call setRegisteredSender on the MessageReceiver contract - const tx = await (receiverContract as any).setRegisteredSender( - sourceChainId, - ethers.zeroPadValue(avalancheSenderAddress, 32) - ); - await tx.wait(); - ``` - -You can find the full code for the `deploySender.ts` and `deployReceiver.ts` below. - -??? code "deploySender.ts" - - ```typescript - import { ethers } from 'ethers'; -import fs from 'fs'; -import path from 'path'; -import dotenv from 'dotenv'; -import { - ChainsConfig, - DeployedContracts, - MessageSenderJson, -} from './interfaces'; - -dotenv.config(); - -async function main(): Promise { - // Load the chain configuration from JSON - const chains: ChainsConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); - - // Get the Avalanche Fuji configuration - const avalancheChain = chains.chains.find((chain) => - chain.description.includes('Avalanche testnet') - ); - if (!avalancheChain) { - throw new Error( - 'Avalanche testnet configuration not found in chains.json.' - ); - } - - // Set up the provider and wallet - const provider = new ethers.JsonRpcProvider(avalancheChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - - // Load the ABI and bytecode of the MessageSender contract - const messageSenderJson: MessageSenderJson = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), - 'utf8' - ) - ); - - const { abi, bytecode } = messageSenderJson; - - // Create a ContractFactory for MessageSender - const MessageSender = new ethers.ContractFactory(abi, bytecode, wallet); - - // Deploy the contract using the Wormhole Relayer address for Avalanche Fuji - const senderContract = await MessageSender.deploy( - avalancheChain.wormholeRelayer - ); - await senderContract.waitForDeployment(); - - console.log('MessageSender deployed to:', senderContract.target); // `target` is the address in ethers.js v6 - - // Update the deployedContracts.json file - const deployedContractsPath = path.resolve( - __dirname, - '../deploy-config/deployedContracts.json' - ); - const deployedContracts: DeployedContracts = JSON.parse( - fs.readFileSync(deployedContractsPath, 'utf8') - ); - - deployedContracts.avalanche = { - MessageSender: senderContract.target as any, - deployedAt: new Date().toISOString(), - }; - - fs.writeFileSync( - deployedContractsPath, - JSON.stringify(deployedContracts, null, 2) - ); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); - - ``` - -??? code "deployReceiver.ts" - - ```typescript - import { ethers } from 'ethers'; -import fs from 'fs'; -import path from 'path'; -import dotenv from 'dotenv'; -import { - ChainsConfig, - DeployedContracts, - MessageReceiverJson, -} from './interfaces'; - -dotenv.config(); - -async function main(): Promise { - // Load the chain configuration from the JSON file - const chains: ChainsConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); - - // Get the Celo Testnet configuration - const celoChain = chains.chains.find((chain) => - chain.description.includes('Celo Testnet') - ); - if (!celoChain) { - throw new Error('Celo Testnet configuration not found.'); - } - - // Set up the provider and wallet - const provider = new ethers.JsonRpcProvider(celoChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - - // Load the ABI and bytecode of the MessageReceiver contract - const messageReceiverJson: MessageReceiverJson = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/MessageReceiver.sol/MessageReceiver.json' - ), - 'utf8' - ) - ); - - const { abi, bytecode } = messageReceiverJson; - - // Create a ContractFactory for MessageReceiver - const MessageReceiver = new ethers.ContractFactory(abi, bytecode, wallet); - - // Deploy the contract using the Wormhole Relayer address for Celo Testnet - const receiverContract = await MessageReceiver.deploy( - celoChain.wormholeRelayer - ); - await receiverContract.waitForDeployment(); - - console.log('MessageReceiver deployed to:', receiverContract.target); // `target` is the contract address in ethers.js v6 - - // Update the deployedContracts.json file - const deployedContractsPath = path.resolve( - __dirname, - '../deploy-config/deployedContracts.json' - ); - const deployedContracts: DeployedContracts = JSON.parse( - fs.readFileSync(deployedContractsPath, 'utf8') - ); - - // Retrieve the address of the MessageSender from the deployedContracts.json file - const avalancheSenderAddress = deployedContracts.avalanche?.MessageSender; - if (!avalancheSenderAddress) { - throw new Error('Avalanche MessageSender address not found.'); - } - - // Define the source chain ID for Avalanche Fuji - const sourceChainId = 6; - - // Call setRegisteredSender on the MessageReceiver contract - const tx = await (receiverContract as any).setRegisteredSender( - sourceChainId, - ethers.zeroPadValue(avalancheSenderAddress, 32) - ); - await tx.wait(); - - console.log( - `Registered MessageSender (${avalancheSenderAddress}) for Avalanche chain (${sourceChainId})` - ); - - deployedContracts.celo = { - MessageReceiver: receiverContract.target as any, - deployedAt: new Date().toISOString(), - }; - - fs.writeFileSync( - deployedContractsPath, - JSON.stringify(deployedContracts, null, 2) - ); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); - - ``` - -### Deploy the Sender Contract - -The sender contract will handle quoting and sending messages cross-chain. - -1. Run the following command to deploy the sender contract: - - ```bash - npm run deploy:sender - ``` - -2. Once deployed, the contract address will be displayed. You may check the contract on the [Avalanche Fuji Explorer](https://testnet.snowtrace.io/){target=\_blank} - -
-npm run deploy:sender - > wormhole-cross-chain@1.0.0 deploy:sender - > node script/deploySender.ts - MessageSender deployed to: 0xf5c474f335fFf617fA6FD04DCBb17E20ee0cEfb1 - -
- - -### Deploy the Receiver Contract - -The receiver contract listens for cross-chain messages and logs them when received. - -1. Deploy the receiver contract with this command: - - ```bash - npm run deploy:receiver - ``` - -2. After deployment, note down the contract address. You may check the contract on the [Celo Alfajores Explorer](https://alfajores.celoscan.io/){target=\_blank}. - - -## Send a Cross-Chain Message - -Now that both the sender and receiver contracts are deployed, let's move on to the next exciting step: sending a cross-chain message from Avalanche Fuji to Celo Alfajores. - -In this example, we will use the `sendMessage.ts` script to transmit a message from the sender contract on Avalanche to the receiver contract on Celo. The script uses [Ethers.js](https://docs.ethers.org/v6/){target=\_blank} to interact with the deployed contracts, calculate the cross-chain cost dynamically, and handle the transaction. - -Let's break down the script step by step. - -1. **Load configuration files** - - 1. **`chains.json`** - contains details about the supported Testnet chains, such as RPC URLs and relayer addresses - 2. **`deployedContracts.json`** - stores the addresses of the deployed sender and receiver contracts. This file is dynamically updated when contracts are deployed, but users can also manually add their own deployed contract addresses if needed - - ```typescript - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); - - const deployedContracts: DeployedContracts = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/deployedContracts.json'), - 'utf8' - ) - ); - ``` - -2. **Configure the provider and signer** - the script first reads the chain configurations and extracts the contract addresses. One essential step in interacting with a blockchain is setting up a _provider_. A provider is your connection to the blockchain network. It allows your script to interact with the blockchain, retrieve data, and send transactions. In this case, we're using a JSON-RPC provider - - Next, we configure the wallet, which will be used to sign transactions. The wallet is created using the private key and the provider. This ensures that all transactions sent from this wallet are broadcast to the Avalanche Fuji network: - - ```typescript - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - ``` - - After setting up the wallet, the script loads the ABI for the `MessageSender.sol` contract and creates an instance of it: - - ```typescript - fs.readFileSync( - path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), - 'utf8' - ) - ); - ``` - -3. **Set up the message details** - the next part of the script defines the target chain (Celo) and the target address (the receiver contract on Celo): - - ```typescript - const targetAddress = deployedContracts.celo.MessageReceiver; - ``` - - You can customize the message that will be sent across chains: - - ```typescript - - ``` - -4. **Estimate cross-chain cost** - before sending the message, we dynamically calculate the cross-chain cost using the `quoteCrossChainCost` function: - - ```typescript - - ``` - - This ensures that the transaction includes enough funds to cover the gas fees for the cross-chain message. - -5. **Send a message** - with everything set up, the message is sent using the `sendMessage` function: - - ```typescript - targetChain, - targetAddress, - message, - { - value: txCost, - } - ); - ``` - - After sending, the script waits for the transaction to be confirmed: - - ```typescript - - ``` - -6. **Run the script** - to send the message, run the following command: - - ```bash - npm run send:message - ``` - -If everything is set up correctly, the message will be sent from the Avalanche Fuji Testnet to the Celo Alfajores Testnet. You can monitor the transaction and verify that the message was received on Celo using the [Wormhole Explorer](https://wormholescan.io/#/?network=TESTNET){target=\_blank}. - -The console should output something similar to this: - -
-npm run send:message - > wormhole-cross-chain@1.0.0 send:message - > node script/sendMessage.ts -Sender Contract Address: 0xD720BFF42a0960cfF1118454A907a44dB358f2b1 -Receiver Contract Address: 0x692550997C252cC5044742D1A2BD91E4f4b46D39 -... -Transaction sent, waiting for confirmation... -... -Message sent! Transaction hash: - 0x9d359a66ba42baced80062229c0b02b4f523fe304aff3473dcf53117aee13fb6 -You may see the transaction status on the Wormhole Explorer: - https://wormholescan.io/#/tx/0x9d359a66ba42baced80062229c0b02b4f523fe304aff3473dcf53117aee13fb6?network=TESTNET - -
- -You can find the full code for the `sendMessage.ts` below. - -??? code "sendMessage.ts" - - ```solidity - import { ethers } from 'ethers'; -import fs from 'fs'; -import path from 'path'; -import dotenv from 'dotenv'; -import { ChainsConfig, DeployedContracts } from './interfaces'; - -dotenv.config(); - -async function main(): Promise { - // Load the chain configuration and deployed contract addresses - const chains: ChainsConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/chains.json'), - 'utf8' - ) - ); - - const deployedContracts: DeployedContracts = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../deploy-config/deployedContracts.json'), - 'utf8' - ) - ); - - console.log( - 'Sender Contract Address: ', - deployedContracts.avalanche.MessageSender - ); - console.log( - 'Receiver Contract Address: ', - deployedContracts.celo.MessageReceiver - ); - console.log('...'); - - // Get the Avalanche Fuji configuration - const avalancheChain = chains.chains.find((chain) => - chain.description.includes('Avalanche testnet') - ); - - if (!avalancheChain) { - throw new Error( - 'Avalanche testnet configuration not found in chains.json.' - ); - } - - // Set up the provider and wallet - const provider = new ethers.JsonRpcProvider(avalancheChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - - // Load the ABI of the MessageSender contract - const messageSenderJson = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../out/MessageSender.sol/MessageSender.json'), - 'utf8' - ) - ); - - const abi = messageSenderJson.abi; - - // Create a contract instance for MessageSender - const MessageSender = new ethers.Contract( - deployedContracts.avalanche.MessageSender, // Automatically use the deployed address - abi, - wallet - ); - - // Define the target chain and target address (the Celo receiver contract) - const targetChain = 14; // Wormhole chain ID for Celo Alfajores - const targetAddress = deployedContracts.celo.MessageReceiver; - - // The message you want to send - const message = 'Hello from Avalanche to Celo!'; - - // Dynamically quote the cross-chain cost - const txCost = await MessageSender.quoteCrossChainCost(targetChain); - - // Send the message (make sure to send enough gas in the transaction) - const tx = await MessageSender.sendMessage( - targetChain, - targetAddress, - message, - { - value: txCost, - } - ); - - console.log('Transaction sent, waiting for confirmation...'); - await tx.wait(); - console.log('...'); - - console.log('Message sent! Transaction hash:', tx.hash); - console.log( - `You may see the transaction status on the Wormhole Explorer: https://wormholescan.io/#/tx/${tx.hash}?network=TESTNET` - ); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); - - ``` - -## Conclusion - -You're now fully equipped to build cross-chain contracts using the Wormhole protocol! With this tutorial, you've learned how to: - -- Deploy sender and receiver contracts on different Testnets -- Send a cross-chain message from one blockchain to another -- Monitor the status of your cross-chain transactions using the Wormhole Explorer and Wormhole-Solidity-SDK ---- END CONTENT --- - -Doc-Content: https://wormhole.com/docs/tutorials/solidity-sdk/cross-chain-token-contracts/ ---- BEGIN CONTENT --- ---- -title: Cross-Chain Token Transfers -description: Learn how to create cross-chain token transfers using Wormhole's Solidity SDK. Build and deploy smart contracts to send tokens from one blockchain to another. ---- - -# Create Cross-Chain Token Transfer Contracts - -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank} - -## Introduction - -In this tutorial, you'll learn how to create a simple cross-chain token transfer system using the Wormhole protocol via the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. We'll guide you through building and deploying smart contracts that enable seamless token transfers of IERC-20 tokens between blockchains. Whether you're a developer looking to explore cross-chain applications or just interested in the Wormhole protocol, this guide will help you understand the fundamentals. - -By the end of this tutorial, you'll have a working cross-chain token transfer system built with the powerful tools provided by the Wormhole Solidity SDK, which you can further customize and integrate into your projects. - -## Prerequisites - -Before you begin, ensure you have the following: - -- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine -- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} for deploying contracts -- Testnet tokens for [Avalanche-Fuji](https://core.app/tools/testnet-faucet/?token=C){target=\_blank} and [Celo-Alfajores](https://faucet.celo.org/alfajores){target=\_blank} to cover gas fees -- [USDC Testnet](https://faucet.circle.com/){target=\_blank} tokens on Avalanche-Fuji or/and Celo-Alfajores for cross-chain transfer -- Wallet private key - -## Valid Tokens for Transfer - -It's important to note that this tutorial leverages [Wormhole's TokenBridge](https://github.com/wormhole-foundation/wormhole/blob/6130bbb6f456b42b789a71f7ea2fd049d632d2fb/ethereum/contracts/bridge/TokenBridge.sol){target=\_blank} to transfer tokens between chains. So, the tokens you'd like to transfer must have an attestation on the `TokenBridge` contract of the target blockchain. - -To simplify this process, we've included a tool for verifying if a token has an attestation on the target chain. This tool uses the [`wrappedAsset`](https://github.com/wormhole-foundation/wormhole/blob/6130bbb6f456b42b789a71f7ea2fd049d632d2fb/ethereum/contracts/bridge/BridgeGetters.sol#L50-L52){target=\_blank} function from the `TokenBridge` contract. If the token has an attestation, the `wrappedAsset` function returns the address of the wrapped token on the target chain; otherwise, it returns the zero address. - -???- tip "Check Token Attestation" - 1. Clone the [repository](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank} and navigate to the project directory: - ```bash - git clone https://github.com/wormhole-foundation/demo-cross-chain-token-transfer.git - cd cross-chain-token-transfers - ``` - 2. Install the dependencies: - ```bash - npm install - ``` - - 3. Run the script to check token attestation: - ```bash - npm run verify - ``` - - 4. Follow the prompts: - - 1. Enter the RPC URL of the target chain - 2. Enter the `TokenBridge` contract address on the target chain - 3. Enter the token contract address on the source chain - 4. Enter the source chain ID - - 5. The expected output when the token has an attestation: - -
-npm run verify - > cross-chain-token-transfer@1.0.0 verify - > npx ts-node script/check-attestation.ts - - Enter the TARGET chain RPC URL: https://alfajores-forno.celo-testnet.org - Enter the Token Bridge contract address on the TARGET chain: 0x05...E153 - Enter the token contract address on the SOURCE chain: 0x54...bc65 - Enter the SOURCE chain ID: 6 - The token is attested on the target chain. Wrapped token address: 0xDDB349c976cA2C873644F21f594767Eb5390C831 - -
- - Using this tool ensures that you only attempt to transfer tokens with verified attestations, avoiding any potential issues during the cross-chain transfer process. - -## Project Setup - -Let's start by initializing a new Foundry project. This will set up a basic structure for our smart contracts. - -1. Open your terminal and run the following command to initialize a new Foundry project: - - ```bash - forge init cross-chain-token-transfers - ``` - - This will create a new directory named `cross-chain-token-transfers` with a basic project structure. This also initializes a new `git` repository. - -2. Navigate into the newly created project directory: - - ```bash - cd cross-chain-token-transfers - ``` - -3. Install the Wormhole Solidity SDK: - - ```bash - forge install wormhole-foundation/wormhole-solidity-sdk - ``` - - To ease development, we'll use the Wormhole Solidity SDK, which provides useful helpers for cross-chain development. - This SDK includes the `TokenSender` and `TokenReceiver` abstract classes, which simplify sending and receiving tokens across chains. - -## Build Cross-Chain Contracts - -In this section, we'll build two smart contracts to send tokens from a source chain and receive them on a target chain. These contracts will interact with the Wormhole protocol to facilitate secure and seamless cross-chain token transfers. - -At a high level, our contracts will: - -1. Send tokens from one blockchain to another using the Wormhole protocol -2. Receive and process the tokens on the target chain, ensuring they are correctly transferred to the intended recipient - -Before diving into the contract implementation steps, let’s first break down the key parts of the contracts. - -### Sender Contract: CrossChainSender - -The `CrossChainSender` contract calculates the cost of sending tokens across chains and then facilitates the actual token transfer. - -Let's start writing the `CrossChainSender` contract: - -1. Create a new file named `CrossChainSender.sol` in the `/src` directory: - - ```bash - touch src/CrossChainSender.sol - ``` - -2. Open the file. First, we'll start with the imports and the contract setup: - - ```solidity - pragma solidity ^0.8.13; - -import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; -import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - -contract CrossChainSender is TokenSender { - uint256 constant GAS_LIMIT = 250_000; - - constructor( - address _wormholeRelayer, - address _tokenBridge, - address _wormhole - ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - - ``` - - This sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. - - With the contract structure in place, define the following functions within its body to enable multichain token transfers. - -3. Next, let's add a function that estimates the cost of sending tokens across chains: - - ```solidity - uint16 targetChain - ) public view returns (uint256 cost) { - uint256 deliveryCost; - (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - 0, - GAS_LIMIT - ); - - cost = deliveryCost + wormhole.messageFee(); - } - ``` - - This function, `quoteCrossChainDeposit`, helps calculate the cost of transferring tokens to a different chain. It factors in the delivery cost and the cost of publishing a message via the Wormhole protocol. - -4. Finally, we'll add the function that sends the tokens across chains: - - ```solidity - uint16 targetChain, - address targetReceiver, - address recipient, - uint256 amount, - address token - ) public payable { - uint256 cost = quoteCrossChainDeposit(targetChain); - require( - msg.value == cost, - "msg.value must equal quoteCrossChainDeposit(targetChain)" - ); - - IERC20(token).transferFrom(msg.sender, address(this), amount); - - bytes memory payload = abi.encode(recipient); - - sendTokenWithPayloadToEvm( - targetChain, - targetReceiver, - payload, - 0, - GAS_LIMIT, - token, - amount - ); - } - ``` - - This `sendCrossChainDeposit` function is where the actual token transfer happens. It sends the tokens to the recipient on the target chain using the Wormhole protocol. - -Here’s a breakdown of what happens in each step of the `sendCrossChainDeposit` function: - -1. **Cost calculation** - the function starts by calculating the cost of the cross-chain transfer using `quoteCrossChainDeposit`(`targetChain`). This cost includes both the delivery fee and the Wormhole message fee. The `sendCrossChainDeposit` function then checks that the user has sent the correct amount of Ether to cover this cost (`msg.value`) - -2. **Token transfer to contract** - the next step is to transfer the specified amount of tokens from the user to the contract itself using `IERC-20(token).transferFrom(msg.sender, address(this), amount)`. This ensures that the contract has custody of the tokens before initiating the cross-chain transfer - -3. **Payload encoding** - The recipient's address on the target chain is encoded into a payload using `abi.encode(recipient)`. This payload will be sent along with the token transfer, so the target contract knows who should receive the tokens on the destination chain - -4. **Cross-chain transfer** - the `sendTokenWithPayloadToEvm` function is called to initiate the cross-chain token transfer. This function: - - Specifies the `targetChain` (the Wormhole chain ID of the destination blockchain). - - Sends the `targetReceiver` contract address on the target chain that will receive the tokens. - - Attaches the payload containing the recipient's address. - - Sets the `GAS_LIMIT` for the transaction. - - Passes the token `address` and `amount` to transfer. - - This triggers the Wormhole protocol to handle the cross-chain messaging and token transfer, ensuring the tokens and payload reach the correct destination on the target chain. - -You can find the complete code for the `CrossChainSender.sol` below. - -??? code "MessageSender.sol" - - ```solidity - // SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; -import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - -contract CrossChainSender is TokenSender { - uint256 constant GAS_LIMIT = 250_000; - - constructor( - address _wormholeRelayer, - address _tokenBridge, - address _wormhole - ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - - // Function to get the estimated cost for cross-chain deposit - function quoteCrossChainDeposit( - uint16 targetChain - ) public view returns (uint256 cost) { - uint256 deliveryCost; - (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( - targetChain, - 0, - GAS_LIMIT - ); - - cost = deliveryCost + wormhole.messageFee(); - } - - // Function to send tokens and payload across chains - function sendCrossChainDeposit( - uint16 targetChain, - address targetReceiver, - address recipient, - uint256 amount, - address token - ) public payable { - uint256 cost = quoteCrossChainDeposit(targetChain); - require( - msg.value == cost, - "msg.value must equal quoteCrossChainDeposit(targetChain)" - ); - - IERC20(token).transferFrom(msg.sender, address(this), amount); - - bytes memory payload = abi.encode(recipient); - - sendTokenWithPayloadToEvm( - targetChain, - targetReceiver, - payload, - 0, - GAS_LIMIT, - token, - amount - ); - } -} - ``` - -### Receiver Contract: CrossChainReceiver - -The `CrossChainReceiver` contract is designed to handle the receipt of tokens and payloads from another blockchain. It ensures that the tokens are correctly transferred to the designated recipient on the receiving chain. - -Let's start writing the `CrossChainReceiver` contract: - -1. Create a new file named `CrossChainReceiver.sol` in the `/src` directory: - - ```bash - touch src/CrossChainReceiver.sol - ``` - -2. Open the file. First, we'll start with the imports and the contract setup: - - ```solidity - pragma solidity ^0.8.13; - -import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; -import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - -contract CrossChainReceiver is TokenReceiver { - // The Wormhole relayer and registeredSenders are inherited from the Base.sol contract - - constructor( - address _wormholeRelayer, - address _tokenBridge, - address _wormhole - ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - - ``` - - Similar to the `CrossChainSender` contract, this sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. - -3. Next, let's add a function inside the contract to handle receiving the payload and tokens: - - ```solidity - bytes memory payload, - TokenReceived[] memory receivedTokens, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 // deliveryHash - ) - internal - override - onlyWormholeRelayer - isRegisteredSender(sourceChain, sourceAddress) - { - require(receivedTokens.length == 1, "Expected 1 token transfer"); - - // Decode the recipient address from the payload - address recipient = abi.decode(payload, (address)); - - // Transfer the received tokens to the intended recipient - IERC20(receivedTokens[0].tokenAddress).transfer( - recipient, - receivedTokens[0].amount - ); - } - ``` - - This `receivePayloadAndTokens` function processes the tokens and payload sent from another chain, decodes the recipient address, and transfers the tokens to them using the Wormhole protocol. This function also validates the emitter (`sourceAddress`) to ensure the message comes from a trusted sender. - - This function ensures that: - - - It only processes one token transfer at a time - - The `sourceAddress` is checked against a list of registered senders using the `isRegisteredSender` modifier, which verifies if the emitter is allowed to send tokens to this contract - - The recipient address is decoded from the payload, and the received tokens are transferred to them using the ERC-20 interface - -After we call `sendTokenWithPayloadToEvm` on the source chain, the message goes through the standard Wormhole message lifecycle. Once a [VAA (Verifiable Action Approval)](/docs/learn/infrastructure/vaas/){target=\_blank} is available, the delivery provider will call `receivePayloadAndTokens` on the target chain and target address specified, with the appropriate inputs. - -??? tip "Understanding the `TokenReceived` Struct" - - Let’s delve into the fields provided to us in the `TokenReceived` struct: - - ```solidity - struct TokenReceived { - bytes32 tokenHomeAddress; - uint16 tokenHomeChain; - address tokenAddress; - uint256 amount; - uint256 amountNormalized; -} - ``` - - - **`tokenHomeAddress`** - the original address of the token on its native chain. This is the same as the token field in the call to `sendTokenWithPayloadToEvm` unless the original token sent is a Wormhole-wrapped token. In that case, this will be the address of the original version of the token (on its native chain) in Wormhole address format (left-padded with 12 zeros) - - - **`tokenHomeChain`** - the Wormhole chain ID corresponding to the home address above. This will typically be the source chain unless the original token sent is a Wormhole-wrapped asset, which will be the chain of the unwrapped version of the token - - - **`tokenAddress`** - the address of the IERC-20 token on the target chain that has been transferred to this contract. If `tokenHomeChain` equals the target chain, this will be the same as `tokenHomeAddress`; otherwise, it will be the Wormhole-wrapped version of the token sent - - - **`amount`** - the token amount sent to you with the same units as the original token. Since `TokenBridge` only sends with eight decimals of precision, if your token has 18 decimals, this will be the "amount" you sent, rounded down to the nearest multiple of 10^10 - - - **`amountNormalized`** - the amount of token divided by (1 if decimals ≤ 8, else 10^(decimals - 8)) - -You can find the complete code for the `CrossChainReceiver.sol` contract below: - -??? code "CrossChainReceiver.sol" - - ```solidity - // SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; -import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - -contract CrossChainReceiver is TokenReceiver { - // The Wormhole relayer and registeredSenders are inherited from the Base.sol contract - - constructor( - address _wormholeRelayer, - address _tokenBridge, - address _wormhole - ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - - // Function to receive the cross-chain payload and tokens with emitter validation - function receivePayloadAndTokens( - bytes memory payload, - TokenReceived[] memory receivedTokens, - bytes32 sourceAddress, - uint16 sourceChain, - bytes32 // deliveryHash - ) - internal - override - onlyWormholeRelayer - isRegisteredSender(sourceChain, sourceAddress) - { - require(receivedTokens.length == 1, "Expected 1 token transfer"); - - // Decode the recipient address from the payload - address recipient = abi.decode(payload, (address)); - - // Transfer the received tokens to the intended recipient - IERC20(receivedTokens[0].tokenAddress).transfer( - recipient, - receivedTokens[0].amount - ); - } -} - ``` - -## Deploy the Contracts - -Now that you've written the `CrossChainSender` and `CrossChainReceiver` contracts, it's time to deploy them to your chosen networks. - -1. **Set up deployment configuration** - before deploying, you must configure the networks and the deployment environment. This information is stored in a configuration file - - 1. Create a directory named deploy-config in the root of your project: - - ```bash - mkdir deploy-config - ``` - - 2. Create a `config.json` file in the `deploy-config` directory: - - ```bash - touch deploy-config/config.json - ``` - - 3. Open the `config.json` file and add the following configuration: - - ```json - { - "chains": [ - { - "description": "Avalanche testnet fuji", - "chainId": 6, - "rpc": "https://api.avax-test.network/ext/bc/C/rpc", - "tokenBridge": "0x61E44E506Ca5659E6c0bba9b678586fA2d729756", - "wormholeRelayer": "0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB", - "wormhole": "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C" - }, - { - "description": "Celo Testnet", - "chainId": 14, - "rpc": "https://alfajores-forno.celo-testnet.org", - "tokenBridge": "0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153", - "wormholeRelayer": "0x306B68267Deb7c5DfCDa3619E22E9Ca39C374f84", - "wormhole": "0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56" - } - ] -} - ``` - - This file specifies the details for each chain where you plan to deploy your contracts, including the RPC URL, the `TokenBridge` address, the Wormhole relayer, and the Wormhole Core Contract. - - For a complete list of Wormhole contract addresses on various blockchains, refer to the [Wormhole Contract Addresses](/docs/build/reference/contract-addresses/){target=_blank}. - - !!! note - You can add your desired chains to this file by specifying the required fields for each chain. In this example, we use the Avalanche Fuji and Celo Alfajores Testnets. - - 4. Create a `contracts.json` file in the `deploy-config` directory: - - ```bash - echo '{}' > deploy-config/contracts.json - ``` - - This file can be left blank initially. It will be automatically updated with the deployed contract addresses after a successful deployment - -2. **Set up your Node.js environment** - you'll need to set up your Node.js environment to run the deployment script - - 1. Initialize a Node.js project: - - ```bash - npm init -y - ``` - - 2. Create a `.gitignore` file to ensure your private key isn't accidentally exposed or committed to version control: +Options: + --help Show help [boolean] + --version Show version number [boolean] + --src-chain source chain [required] [choices: + 'solana', + 'ethereum', + 'terra', + 'bsc', + 'polygon', + 'avalanche', + 'oasis', + 'algorand', + 'aurora', + 'fantom', + 'karura', + 'acala', + 'klaytn', + 'celo', + 'near', + 'moonbeam', + 'neon', + 'terra2', + 'injective', + 'osmosis', + 'sui', + 'aptos', + 'arbitrum', + 'optimism', + 'gnosis', + 'pythnet', + 'xpla', + 'btc', + 'base', + 'sei', + 'rootstock', + 'scroll', + 'mantle', + 'blast', + 'xlayer', + 'linea', + 'berachain', + 'seievm', + 'wormchain', + 'cosmoshub', + 'evmos', + 'kujira', + 'neutron', + 'celestia', + 'stargaze', + 'seda', + 'dymension', + 'provenance', + 'sepolia', + 'arbitrum_sepolia', + 'base_sepolia', + 'optimism_sepolia', + 'holesky', + 'polygon_sepolia'] + --dst-chain destination chain + [required] [choices: + 'solana', + 'ethereum', + 'terra', + 'bsc', + 'polygon', + 'avalanche', + 'oasis', + 'algorand', + 'aurora', + 'fantom', + 'karura', + 'acala', + 'klaytn', + 'celo', + 'near', + 'moonbeam', + 'neon', + 'terra2', + 'injective', + 'osmosis', + 'sui', + 'aptos', + 'arbitrum', + 'optimism', + 'gnosis', + 'pythnet', + 'xpla', + 'btc', + 'base', + 'sei', + 'rootstock', + 'scroll', + 'mantle', + 'blast', + 'xlayer', + 'linea', + 'berachain', + 'seievm', + 'wormchain', + 'cosmoshub', + 'evmos', + 'kujira', + 'neutron', + 'celestia', + 'stargaze', + 'seda', + 'dymension', + 'provenance', + 'sepolia', + 'arbitrum_sepolia', + 'base_sepolia', + 'optimism_sepolia', + 'holesky', + 'polygon_sepolia'] + --dst-addr destination address [string] [required] + --token-addr token address [string] [default: native token] + --amount token amount [string] [required] + -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] + --rpc RPC endpoint [string] + ``` +??? interface "Verify VAA" ```bash - echo ".env" >> .gitignore - ``` - - 3. Install the necessary dependencies: + worm verify-vaa INSERT_VAA, INSERT_NETWORK - ```bash - npm install ethers dotenv readline-sync @types/readline-sync - ``` +Options: + --help Show help [boolean] + --version Show version number [boolean] + -v, --vaa vaa in hex format [string] [required] + -n, --network Network [required] [choices: "mainnet", "testnet", "devnet"] + ``` - These dependencies are required for the deployment script to work properly. +## Examples -3. **Compile your smart contracts** - compile your smart contracts using Foundry. This ensures that your contracts are up-to-date and ready for deployment +### Generate a VAA - - Run the following command to compile your contracts: +Use `generate` to create VAAs for testing. For example, use the following command to create an NFT bridge registration VAA: - ```bash - forge build - ``` +```bash +worm generate registration --module NFTBridge \ + --chain bsc \ + --contract-address 0x706abc4E45D419950511e474C7B9Ed348A4a716c \ + --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 +``` - This will generate the necessary ABI and bytecode files in a directory named `/out`. +The below example generates a token attestation VAA: - The expected output should be similar to this: +```bash +worm generate attestation --emitter-chain ethereum \ + --emitter-address 11111111111111111111111111111115 \ + --chain ethereum \ + --token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \ + --decimals 6 \ + --symbol USDC \ + --name USDC \ + --guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0 +``` -
-forge build - > [⠒] Compiling... - > [⠰] Compiling 30 files with 0.8.23 - [⠔] Solc 0.8.23 finished in 2.29s -Compiler run successful! - -
+### Parse a VAA -4. **Write the deployment script** - you’ll need a script to automate the deployment of your contracts. Let’s create the deployment script +Use `parse` to parse a VAA into JSON: - 1. Create a new file named `deploy.ts` in the `/script` directory: +```bash +worm parse $(worm-fetch-governance 13940208096455381020) +``` - ```bash - touch script/deploy.ts - ``` +This example will fetch governance VAA `13940208096455381020` and print it as JSON: - 2. Open the file and load imports and configuration: +```bash +# ...signatures elided +timestamp: 1651416474, +nonce: 1570649151, +emitterChain: 1, +emitterAddress: '0000000000000000000000000000000000000000000000000000000000000004', +sequence: 13940208096455381020n, +consistencyLevel: 32, +payload: { + module: 'Core', + type: 'GuardianSetUpgrade', + chain: 0, + newGuardianSetIndex: 2, + newGuardianSetLength: 19, + newGuardianSet: [ + '58cc3ae5c097b213ce3c81979e1b9f9570746aa5', + 'ff6cb952589bde862c25ef4392132fb9d4a42157', + '114de8460193bdf3a2fcf81f86a09765f4762fd1', + '107a0086b32d7a0977926a205131d8731d39cbeb', + '8c82b2fd82faed2711d59af0f2499d16e726f6b2', + '11b39756c042441be6d8650b69b54ebe715e2343', + '54ce5b4d348fb74b958e8966e2ec3dbd4958a7cd', + '66b9590e1c41e0b226937bf9217d1d67fd4e91f5', + '74a3bf913953d695260d88bc1aa25a4eee363ef0', + '000ac0076727b35fbea2dac28fee5ccb0fea768e', + 'af45ced136b9d9e24903464ae889f5c8a723fc14', + 'f93124b7c738843cbb89e864c862c38cddcccf95', + 'd2cc37a4dc036a8d232b48f62cdd4731412f4890', + 'da798f6896a3331f64b48c12d1d57fd9cbe70811', + '71aa1be1d36cafe3867910f99c09e347899c19c3', + '8192b6e7387ccd768277c17dab1b7a5027c0b3cf', + '178e21ad2e77ae06711549cfbb1f9c7a9d8096e8', + '5e1487f35515d02a92753504a8d75471b9f49edb', + '6fbebc898f403e4773e95feb15e80c9a99c8348d' + ] +} +``` - ```typescript - import * as fs from 'fs'; -import * as path from 'path'; -import * as dotenv from 'dotenv'; -import readlineSync from 'readline-sync'; +### Submit VAAs -dotenv.config(); - ``` +Use `submit` to submit a VAA to a chain. It first parses the VAA and determines the destination chain and module. For example, a contract upgrade contains both the target chain and module, so the only required argument is the network moniker (`mainnet` or `testnet`): - Import the required libraries and modules to interact with Ethereum, handle file paths, load environment variables, and enable user interaction via the terminal. +```bash +worm submit $(cat my-nft-registration.txt) --network mainnet +``` - 3. Define interfaces to use for chain configuration and contract deployment: +The script will ask you to specify the target chain for VAAs that don't have a specific target chain (like registrations or Guardian set upgrades). For example, to submit a Guardian set upgrade on all chains, simply run: - ```typescript - description: string; - chainId: number; - rpc: string; - tokenBridge: string; - wormholeRelayer: string; - wormhole: string; -} +```bash +worm-fetch-governance 13940208096455381020 > guardian-upgrade.txt +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain oasis +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain aurora +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain fantom +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain karura +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain acala +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain klaytn +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain avalanche +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain polygon +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain bsc +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain solana +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain terra +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain ethereum +worm submit $(cat guardian-upgrade.txt) --network mainnet --chain celo +``` -interface DeployedContracts { - [chainId: number]: { - networkName: string; - CrossChainSender?: string; - CrossChainReceiver?: string; - deployedAt: string; - }; -} - ``` +The VAA payload type (Guardian set upgrade) specifies that this VAA should go to the core bridge, and the tool directs it there. - These interfaces define the structure of the chain configuration and the contract deployment details. +### Fetch Contract Information - 4. Load and select the chains for deployment: +To get info about a contract (only EVM supported at this time), use the following command: - ```typescript - const configPath = path.resolve(__dirname, '../deploy-config/config.json'); - return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; -} +```bash +worm evm info -c bsc -n mainnet -m TokenBridge +``` -function selectChain( - chains: ChainConfig[], - role: 'source' | 'target' -): ChainConfig { - console.log(`\nSelect the ${role.toUpperCase()} chain:`); - chains.forEach((chain, index) => { - console.log(`${index + 1}: ${chain.description}`); - }); +Running this command generates the following output: - const chainIndex = - readlineSync.questionInt( - `\nEnter the number for the ${role.toUpperCase()} chain: ` - ) - 1; - return chains[chainIndex]; +```bash +{ + "address": "0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7", + "wormhole": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B", + "implementation": "0x621199f6beB2ba6fbD962E8A52A320EA4F6D4aA3", + "isInitialized": true, + "tokenImplementation": "0x7f8C5e730121657E17E452c5a1bA3fA1eF96f22a", + "chainId": 4, + "finality": 15, + "evmChainId": "56", + "isFork": false, + "governanceChainId": 1, + "governanceContract": "0x0000000000000000000000000000000000000000000000000000000000000004", + "WETH": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "registrations": { + "Solana": "0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5", + "Ethereum": "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585", + "Terra": "0x0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2", + "Polygon": "0x0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde", + "Avalanche": "0x0000000000000000000000000e082f06ff657d94310cb8ce8b0d9a04541d8052", + "Oasis": "0x0000000000000000000000005848c791e09901b40a9ef749f2a6735b418d7564", + "Algorand": "0x67e93fa6c8ac5c819990aa7340c0c16b508abb1178be9b30d024b8ac25193d45", + "Aurora": "0x00000000000000000000000051b5123a7b0f9b2ba265f9c4c8de7d78d52f510f", + "Fantom": "0x0000000000000000000000007c9fc5741288cdfdd83ceb07f3ea7e22618d79d2", + "Karura": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624", + "Acala": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624", + "Klaytn": "0x0000000000000000000000005b08ac39eaed75c0439fc750d9fe7e1f9dd0193f", + "Celo": "0x000000000000000000000000796dff6d74f3e27060b71255fe517bfb23c93eed", + "Near": "0x148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7", + "Moonbeam": "0x000000000000000000000000b1731c586ca89a23809861c6103f0b96b3f57d92", + "Neon": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Terra2": "0xa463ad028fb79679cfc8ce1efba35ac0e77b35080a1abe9bebe83461f176b0a3", + "Injective": "0x00000000000000000000000045dbea4617971d93188eda21530bc6503d153313", + "Osmosis": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Sui": "0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5", + "Aptos": "0x0000000000000000000000000000000000000000000000000000000000000001", + "Arbitrum": "0x0000000000000000000000000b2402144bb366a632d14b83f244d2e0e21bd39c", + "Optimism": "0x0000000000000000000000001d68124e65fafc907325e3edbf8c4d84499daa8b", + "Gnosis": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Pythnet": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Xpla": "0x8f9cf727175353b17a5f574270e370776123d90fd74956ae4277962b4fdee24c", + "Btc": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Base": "0x0000000000000000000000008d2de8d2f73f1f4cab472ac9a881c9b123c79627", + "Sei": "0x86c5fd957e2db8389553e1728f9c27964b22a8154091ccba54d75f4b10c61f5e", + "Rootstock": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Scroll": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", + "Mantle": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", + "Blast": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d", + "Xlayer": "0x0000000000000000000000005537857664b0f9efe38c9f320f75fef23234d904", + "Linea": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Berachain": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Seievm": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Snaxchain": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Wormchain": "0xaeb534c45c3049d380b9d9b966f9895f53abd4301bfaff407fa09dea8ae7a924", + "Cosmoshub": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Evmos": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Kujira": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Neutron": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Celestia": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Stargaze": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Seda": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Dymension": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Provenance": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ArbitrumSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", + "BaseSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", + "OptimismSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Holesky": "0x0000000000000000000000000000000000000000000000000000000000000000", + "PolygonSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000" + } } - ``` +``` - The `loadConfig` function reads the chain configuration from the `config.json` file, and the `selectChain` function allows the user to choose the source and target chains for deployment interactively. The user is prompted in the terminal to select which chains to use, making the process interactive and user-friendly. +You can get the contract address for a module as follows: - 5. Define the main function for deployment and load the chain configuration: +```bash +worm info rpc INSERT_NETWORK INSERT_CHAIN INSERT_MODULE +``` - ```typescript - const chains = loadConfig(); +To get the contract address for `NFTBridge` on BSC Mainnet, for example, you can provide the following command: - const sourceChain = selectChain(chains, 'source'); - const targetChain = selectChain(chains, 'target'); - ``` +```bash +worm info contract mainnet bsc NFTBridge +``` - - The `main` function is the entry point for the deployment script - - We then call the `loadConfig` function we previously defined to load the chain configuration from the `config.json` file +### Fetch Chain Information - 6. Set up provider and wallet: - - ```typescript - const targetProvider = new ethers.JsonRpcProvider(targetChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); - ``` - - The scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction on the source chain. +You can get the RPC address for a chain as follows: - 7. Read the compiled contracts: +```bash +worm info rpc INSERT_NETWORK INSERT_CHAIN +``` - ```typescript - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainSender.sol/CrossChainSender.json' - ), - 'utf8' - ) - ); - ``` +To get the RPC address for BSC Mainnet, for example, you can provide the following command: - - This code reads the `CrossChainSender.json` file, the compiled output of the `CrossChainSender.sol` contract - - The file is in the `../out/` directory, which contains the ABI (Application Binary Interface) and bytecode generated during contract compilation - - It uses the `fs.readFileSync` function to read the file and `JSON.parse` to convert the file contents (in JSON format) into a JavaScript object +```bash +worm info rpc mainnet bsc +``` +--- END CONTENT --- - 8. Extract the contract ABI and bytecode: +Doc-Content: https://wormhole.com/docs/tools/dev-env/ +--- BEGIN CONTENT --- +--- +title: Local Dev Environment +description: Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more. +categories: Solidity-SDK, Typescript-SDK +--- - ```typescript - const bytecode = senderJson.bytecode; - ``` +# Development Environment - - **ABI (Application Binary Interface)** - defines the structure of the contract’s functions, events, and data types, allowing the front end to interact with the contract on the blockchain - - **Bytecode** - this is the compiled machine code that will be deployed to the blockchain to create the contract +Developers building for smart contract integration will want to set up a development environment to allow testing the full integration, possibly including VAA generation and relaying. - 9. Create the Contract Factory: +## Tooling Installation - ```typescript - abi, - bytecode, - wallet - ); - ``` +The [Wormhole CLI Tool](/docs/tools/cli/get-started/){target=\_blank} should be installed regardless of the environments chosen. Each environment has its own set of recommended tools. To begin working with a specific environment, see the recommended tools on the respective [environment page](/docs/products/reference/supported-networks/){target=\_blank}. - - **`ethers.ContractFactory`** - creates a new contract factory using the ABI, bytecode, and a wallet (representing the signer). The contract factory is responsible for deploying instances of the contract to the blockchain - - This is a crucial step for deploying the contract since the factory will create and deploy the `CrossChainSender` contract +## Development Stages - 10. Deploy the `CrossChainSender` and `CrossChainReceiver` contracts: +Different approaches to development and testing are recommended at various stages of application development. - === "`CrossChainSender`" - ```typescript - const senderContract = await CrossChainSenderFactory.deploy( - sourceChain.wormholeRelayer, - sourceChain.tokenBridge, - sourceChain.wormhole - ); - await senderContract.waitForDeployment(); - ``` +### Initial Development - === "`CrossChainReceiver`" - ```typescript - process.env.PRIVATE_KEY!, - targetProvider - ); - const receiverJson = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainReceiver.sol/CrossChainReceiver.json' - ), - 'utf8' - ) - ); - const CrossChainReceiverFactory = new ethers.ContractFactory( - receiverJson.abi, - receiverJson.bytecode, - targetWallet - ); +During the initial development of an on-chain application, the best option is to use the native tools available in the environment. You can visit the following resources for more information: - const receiverContract = await CrossChainReceiverFactory.deploy( - targetChain.wormholeRelayer, - targetChain.tokenBridge, - targetChain.wormhole - ); - await receiverContract.waitForDeployment(); - ``` +- **[Environment](https://github.com/wormhole-foundation/wormhole){target=\_blank}** - select the folder for the desired network to learn about the recommended native toolset +- **[Mock Guardian](https://github.com/wormhole-foundation/wormhole/blob/main/sdk/js/src/mock/wormhole.ts){target=\_blank}** - it's recommended to set up a mock Guardian or Emitter to provide signed VAAsFor any program methods that require some message be sent or received. +- **[Wormhole Scaffolding repository](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/evm/ts-test/01_hello_world.ts){target=\_blank}** - example mock Guardian test - Both functions deploy the respective contracts to the selected chains. +Relying on native tools when possible allows for more rapid prototyping and iteration. - For the `CrossChainReceiver` contract: +### Integration - - It defines the wallet related to the target chain - - The logic reads the compiled ABI and bytecode from the JSON file generated during compilation - - It creates a new contract factory using the ABI, bytecode, and wallet - - It deploys the contract to the selected chain passing in the Wormhole Relayer, `TokenBridge`, and Wormhole addresses +For integration to Wormhole and with multiple chains, the simplest option is to use the chains' Testnets. In choosing which chains to use for integration testing, consider which chains in a given environment provide easy access to Testnet tokens and where block times are fast. Find links for Testnet faucets in the [blockchain details section](/docs/products/reference/supported-networks/){target=\_blank}. A developer may prefer standing up a set of local validators instead of using the Testnet. For this option, [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} is available to run local instances of all the chains Wormhole supports. - 11. Save the deployed contract addresses: +!!! note + Variation in host environments causes unique issues, and the computational intensity of multiple simultaneous local validators can make setting them up difficult or time-consuming. You may prefer Testnets for the simplest integration testing. - === "`senderAddress`" - ```typescript - console.log( - `CrossChainSender on ${sourceChain.description}: ${senderAddress}` - ); - ``` +### Prepare for Deployment - === "`receiverAddress`" - ```typescript - console.log( - `CrossChainReceiver on ${targetChain.description}: ${receiverAddress}` - ); - ``` +Once you've finished the application's initial development and performed integration testing, you should set up a CI test environment. The best option for that is likely to be [Tilt](https://tilt.dev/){target=\_blank} since it allows you to spin up any chains supported by Wormhole in a consistent environment. - You may display the deployed contract addresses in the terminal or save them to a JSON file for future reference. +## Validator Setup with Tilt - 12. Register the `CrossChainSender` address on the target chain: +### Tilt +If you'd like to set up a local validator environment, follow the setup guide for Tilt. Tilt is a full-fledged Kubernetes deployment of every chain connected to Wormhole, along with a Guardian node. It usually takes 30 minutes to spin up fully, but it comes with all chains running out of the box. Refer to the [Tilt](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} page for a complete guide to setting up and configuring Tilt. - ```typescript - receiverAddress, - receiverJson.abi, - targetWallet - ); +## Deploying to Public Networks - const tx = await CrossChainReceiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) - ); +### Testnet - await tx.wait(); - ``` +When doing integration testing on Testnets, remember that a single Guardian node is watching for transactions on various test networks. Because Testnets only have a single Guardian, there's a slight chance that your VAAs won't be processed. This rate doesn't indicate performance on Mainnet, where 19 Guardians are watching for transactions. The Testnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Testnet endpoint: - After you deploy the `CrossChainReceiver` contract on the target network, the sender contract address from the source chain needs to be registered. This ensures that only messages from the registered `CrossChainSender` contract are processed. +```text +https://api.testnet.wormholescan.io +``` - This additional step is essential to enforce emitter validation, preventing unauthorized senders from delivering messages to the `CrossChainReceiver` contract. +### Mainnet - 13. Save the deployment details: +The Mainnet contract addresses are available on the page for each [environment](/docs/products/reference/supported-networks/){target=\_blank}. The [Wormholescan API](https://docs.wormholescan.io){target=\_blank} offers the following Guardian equivalent Mainnet endpoint: - ???- example "Save Deployment Details Example" - ```typescript - __dirname, - '../deploy-config/contracts.json' - ); - let deployedContracts: DeployedContracts = {}; +```text +https://api.wormholescan.io +``` +--- END CONTENT --- - if (fs.existsSync(deployedContractsPath)) { - deployedContracts = JSON.parse( - fs.readFileSync(deployedContractsPath, 'utf8') - ); - } +Doc-Content: https://wormhole.com/docs/tools/faqs/ +--- BEGIN CONTENT --- +--- +title: Toolkit FAQs +description: FAQs on Wormhole Toolkit, covering Wormholescan, CLI, SDKs (TypeScript, Solidity), Tilt, error handling, transaction history, and manual VAA submission. +categories: Solidity-SDK, Typescript-SDK +--- - // Update the contracts.json file: - // If a contract already exists on a chain, update its address; otherwise, add a new entry. - if (!deployedContracts[sourceChain.chainId]) { - deployedContracts[sourceChain.chainId] = { - networkName: sourceChain.description, - deployedAt: new Date().toISOString(), - }; - } - deployedContracts[sourceChain.chainId].CrossChainSender = - senderAddress.toString(); - deployedContracts[sourceChain.chainId].deployedAt = - new Date().toISOString(); +# Toolkit FAQs - if (!deployedContracts[targetChain.chainId]) { - deployedContracts[targetChain.chainId] = { - networkName: targetChain.description, - deployedAt: new Date().toISOString(), - }; - } - deployedContracts[targetChain.chainId].CrossChainReceiver = - receiverAddress.toString(); - deployedContracts[targetChain.chainId].deployedAt = - new Date().toISOString(); +## Why does the `toNative` function in the TypeScript SDK return an error? - // Save the updated contracts.json file - fs.writeFileSync( - deployedContractsPath, - JSON.stringify(deployedContracts, null, 2) - ); - ``` - - Add your desired logic to save the deployed contract addresses in a JSON file (or another format). This will be important later when transferring tokens, as you'll need these addresses to interact with the deployed contracts. +The `toNative` function may return an error if the platform-specific module (such as Solana or EVM) is not correctly imported or passed into the Wormhole constructor. - 14. Handle errors and finalize the script: +To fix this, ensure the relevant platform module is imported and included when initializing Wormhole. For example, if you're working with Solana, make sure to import the Solana module and pass it into the Wormhole constructor like this: - ```typescript - if (error.code === 'INSUFFICIENT_FUNDS') { - console.error( - 'Error: Insufficient funds for deployment. Please make sure your wallet has enough funds to cover the gas fees.' - ); - } else { - console.error('An unexpected error occurred:', error.message); - } - process.exit(1); - } -} +```typescript +import solana from '@wormhole-foundation/sdk/solana'; +const wh = await wormhole('Testnet', [solana]); +``` -main().catch((error) => { - console.error(error); - process.exit(1); -}); - ``` +## How can I retrieve the history of previously bridged transactions? + +To retrieve the history of previously bridged transactions, you can use the Wormholescan API. Use the following endpoint to query the transaction history for a specific address: - The try-catch block wraps the deployment logic to catch any errors that may occur. +```bash +https://api.wormholescan.io/api/v1/operations?address=INSERT_ADDRESS +``` - - If the error is due to insufficient funds, it logs a clear message about needing more gas fees - - For any other errors, it logs the specific error message to help with debugging +Simply replace `INSERT_ADDRESS_HERE` with the address you want to query. The API will return a list of operations, including details about previously bridged transactions. - The `process.exit(1)` ensures that the script exits with a failure status code if any error occurs. +???- example "Fetch transaction history for a specific address" + ```bash + curl -X GET "https://api.wormholescan.io/api/v1/operations?address=0x05c009C4C1F1983d4B915C145F4E782de23d3A38" -H "accept: application/json" + ``` - You can find the full code for the `deploy.ts` file below: +## How can I manually submit a VAA to a destination chain in the correct format? - ??? code "deploy.ts" +To manually submit a VAA (Verifiable Action Approval) to a destination chain, follow these steps: - ```solidity - import { BytesLike, ethers } from 'ethers'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as dotenv from 'dotenv'; -import readlineSync from 'readline-sync'; +1. **Obtain the VAA in Base64 format** - navigate to the **Advanced** tab in [Wormholescan](https://wormholescan.io/){target=\_blank} to find the VAA associated with the transaction you want to submit and copy the VAA in base64 format -dotenv.config(); + ```bash + https://wormholescan.io/#/tx/INSERT_TX_HASH?view=advanced + ``` -interface ChainConfig { - description: string; - chainId: number; - rpc: string; - tokenBridge: string; - wormholeRelayer: string; - wormhole: string; -} +2. **Convert the VAA to hex** - you must convert the base64 VAA into a hexadecimal (hex) format before submitting it to the destination chain. This can be done using various online tools or via command-line utilities like `xxd` or a script in a language like Python -interface DeployedContracts { - [chainId: number]: { - networkName: string; - CrossChainSender?: string; - CrossChainReceiver?: string; - deployedAt: string; - }; -} +3. **Submit the VAA through Etherscan (for EVM chains)** - once the VAA is in hex format, go to the [Etherscan UI](https://etherscan.io/){target=\_blank} and submit it through the [`TokenBridge`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/ITokenBridge.sol){target=\_blank} contract’s method (such as the `CompleteTransfer` function or `CompleteTransferWithPayload`) -function loadConfig(): ChainConfig[] { - const configPath = path.resolve(__dirname, '../deploy-config/config.json'); - return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; -} + - The `TokenBridge` contract addresses for each chain are available in the [Wormhole contract addresses](/docs/products/reference/contract-addresses/){target=\_blank} section -function selectChain( - chains: ChainConfig[], - role: 'source' | 'target' -): ChainConfig { - console.log(`\nSelect the ${role.toUpperCase()} chain:`); - chains.forEach((chain, index) => { - console.log(`${index + 1}: ${chain.description}`); - }); + - Interact with the smart contract through the Etherscan UI by pasting the hex-encoded VAA into the appropriate field - const chainIndex = - readlineSync.questionInt( - `\nEnter the number for the ${role.toUpperCase()} chain: ` - ) - 1; - return chains[chainIndex]; -} +Following these steps, you can manually submit a VAA in the proper format to a destination chain. +--- END CONTENT --- -async function main() { - const chains = loadConfig(); +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/get-started/ +--- BEGIN CONTENT --- +--- +title: Get Started with the Solidity SDK +description: Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +categories: Basics, Solidity-SDK +--- - const sourceChain = selectChain(chains, 'source'); - const targetChain = selectChain(chains, 'target'); +# Get Started with the Solidity SDK - const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); - const targetProvider = new ethers.JsonRpcProvider(targetChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); +The [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} provides Solidity interfaces, prebuilt contracts, and testing tools to help Solidity developers build on-chain Wormhole integrations via smart contracts. You can use the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} for off-chain integrations without writing Solidity. - const senderJson = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainSender.sol/CrossChainSender.json' - ), - 'utf8' - ) - ); +## Install the SDK - const abi = senderJson.abi; - const bytecode = senderJson.bytecode; +Use Foundry's [`forge`](https://book.getfoundry.sh/forge/){target=\_blank} to install the SDK using the following command: - const CrossChainSenderFactory = new ethers.ContractFactory( - abi, - bytecode, - wallet - ); +```bash +forge install wormhole-foundation/wormhole-solidity-sdk +``` - try { - const senderContract = await CrossChainSenderFactory.deploy( - sourceChain.wormholeRelayer, - sourceChain.tokenBridge, - sourceChain.wormhole - ); - await senderContract.waitForDeployment(); +## Key Components - // Safely access the deployed contract's address - const senderAddress = (senderContract as ethers.Contract).target; - console.log( - `CrossChainSender on ${sourceChain.description}: ${senderAddress}` - ); +The following key components and features work together to make your on-chain Wormhole integration easier to build. - const targetWallet = new ethers.Wallet( - process.env.PRIVATE_KEY!, - targetProvider - ); - const receiverJson = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainReceiver.sol/CrossChainReceiver.json' - ), - 'utf8' - ) - ); - const CrossChainReceiverFactory = new ethers.ContractFactory( - receiverJson.abi, - receiverJson.bytecode, - targetWallet - ); +??? interface "Base contracts" - const receiverContract = await CrossChainReceiverFactory.deploy( - targetChain.wormholeRelayer, - targetChain.tokenBridge, - targetChain.wormhole - ); - await receiverContract.waitForDeployment(); + Leverage base contracts to send and receive messages and tokens. - // Safely access the deployed contract's address - const receiverAddress = (receiverContract as ethers.Contract).target; - console.log( - `CrossChainReceiver on ${targetChain.description}: ${receiverAddress}` - ); + - [**`Base.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Base.sol){target=\_blank}: Uses Wormhole interfaces to authorize and verify a registered sender. + - [**`TokenBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol){target=\_blank}: Uses `TokenReceiver` and `TokenSender` contracts to define functions for transferring tokens. + - [**`CCTPBase.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPBase.sol){target=\_blank}: Uses `CCTPSender` and `CCTPReceiver` contracts to define functions for transferring USDC. - // Register the sender contract in the receiver contract - console.log( - `Registering CrossChainSender (${senderAddress}) as a valid sender in CrossChainReceiver (${receiverAddress})...` - ); +??? interface "Interfaces" - const CrossChainReceiverContract = new ethers.Contract( - receiverAddress, - receiverJson.abi, - targetWallet - ); + Use interfaces to ensure consistent interactions with the protocol regardless of the supported chain you use. - const tx = await CrossChainReceiverContract.setRegisteredSender( - sourceChain.chainId, - ethers.zeroPadValue(senderAddress as BytesLike, 32) - ); + - [**`ITokenBridge.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/ITokenBridge.sol){target=\_blank}: Defines key structs and functions for token attestation, wrapping and transferring tokens, monitoring transaction progress. + - [**CCTP Interfaces**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/tree/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/CCTPInterfaces){target=\_blank}: A set of interfaces for USDC transfers via CCTP for sending, relaying, and receiving messages and tokens. + - [**`IWormholeReceiver.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeReceiver.sol){target=\_blank}: Defines the `receiveWormholeMessages` function. + - [**`IWormholeRelayer.sol`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol){target=\_blank}: Defines key structs and functions to identify, send, and deliver messages and follow the progress of transactions. - await tx.wait(); - console.log( - `CrossChainSender registered as a valid sender on ${targetChain.description}` - ); +??? interface "Constants" - // Load existing deployed contract addresses from contracts.json - const deployedContractsPath = path.resolve( - __dirname, - '../deploy-config/contracts.json' - ); - let deployedContracts: DeployedContracts = {}; + Auto-generated Solidity constants help avoid manual entry errors and ensure consistent delivery. - if (fs.existsSync(deployedContractsPath)) { - deployedContracts = JSON.parse( - fs.readFileSync(deployedContractsPath, 'utf8') - ); - } + - [**Wormhole Chain ID's**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/Chains.sol){target=\_blank}: Generated list of Wormhole Chain ID's for supported chains. + - [**Circle CCTP Domain IDs**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/CCTPAndTokenBase.sol){target=\_blank}: Generated list of defined CCTP domain ID's to ensure USDC transfers use the correct domain for a given chain. + - [**`chainConsts.ts`**](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/75ddcec06ffe9d62603d023357caa576c5ea101c/gen/chainConsts.ts){target=\_blank}: Returns values to identify properties and contract addresses for each supported chain. - // Update the contracts.json file: - // If a contract already exists on a chain, update its address; otherwise, add a new entry. - if (!deployedContracts[sourceChain.chainId]) { - deployedContracts[sourceChain.chainId] = { - networkName: sourceChain.description, - deployedAt: new Date().toISOString(), - }; - } - deployedContracts[sourceChain.chainId].CrossChainSender = - senderAddress.toString(); - deployedContracts[sourceChain.chainId].deployedAt = - new Date().toISOString(); +## Example Usage - if (!deployedContracts[targetChain.chainId]) { - deployedContracts[targetChain.chainId] = { - networkName: targetChain.description, - deployedAt: new Date().toISOString(), - }; - } - deployedContracts[targetChain.chainId].CrossChainReceiver = - receiverAddress.toString(); - deployedContracts[targetChain.chainId].deployedAt = - new Date().toISOString(); +The following demo illustrates the use of Wormhole Solidity SDK-based smart contracts to send testnet USDC between supported chains. - // Save the updated contracts.json file - fs.writeFileSync( - deployedContractsPath, - JSON.stringify(deployedContracts, null, 2) - ); - } catch (error: any) { - if (error.code === 'INSUFFICIENT_FUNDS') { - console.error( - 'Error: Insufficient funds for deployment. Please make sure your wallet has enough funds to cover the gas fees.' - ); - } else { - console.error('An unexpected error occurred:', error.message); - } - process.exit(1); - } -} +### Prerequisites +Before you begin, ensure you have the following: -main().catch((error) => { - console.error(error); - process.exit(1); -}); - ``` +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Foundry](https://book.getfoundry.sh/getting-started/installation){target=\_blank} installed +- Testnet tokens for two supported chains. This example uses [testnet AVAX for Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [testnet CELO for Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} and can be adapted to any supported chains +- [USDC testnet tokens](https://faucet.circle.com/){target=\_blank} on your source chain for cross-chain transfer -5. **Add your private key** - you'll need to provide your private key. It allows your deployment script to sign the transactions that deploy the smart contracts to the blockchain. Without it, the script won't be able to interact with the blockchain on your behalf +### Set Up a Project - Create a `.env` file in the root of the project and add your private key: +Follow these steps to prepare your development environment: + +1. Create a directory for your project, navigate into it, and install the Wormhole Solidity SDK: ```bash - touch .env + mkdir solidity-token-transfer + cd solidity-token-transfer + forge install wormhole-foundation/wormhole-solidity-sdk ``` - Inside `.env`, add your private key in the following format: +2. Install dependencies for use with your transfer script, including the Wormhole TypeScript SDK, and initiate a new Node.js project: - ```env - PRIVATE_KEY=INSERT_PRIVATE_KEY + ```bash + npm init -y && npm install @wormhole-foundation/sdk ethers -D tsx typescript ``` - -6. **Run the deployment script** - - 1. Open a terminal and run the following command: - - ```bash - npx ts-node script/deploy.ts - ``` - This will execute the deployment script, deploying both contracts to the selected chains. +### Create and Deploy Contracts - 2. Check the deployment output: +This project uses sender and receiver contracts to access the `WormholeRelayer` interface's [`TokenSender`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L24){target=\_blank} and [`TokenReceiver`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/baa085006586a43c42858d355e3ffb743b80d7a4/src/WormholeRelayer/TokenBase.sol#L147){target=\_blank} base classes to simplify sending tokens across chains. - - You will see the deployed contract addresses printed in the terminal if successful. The `contracts.json` file will be updated with these addresses - - If you encounter an error, the script will provide feedback, such as insufficient funds for gas +Follow these steps to create and deploy your sender and receiver Solidity contracts: -If you followed the logic provided in the full code above, your terminal output should look something like this: +1. Use the following example code to create `CrossChainSender.sol`: -
-npx ts-node deploy.ts - > cross-chain-token-transfer@1.0.0 deploy - > npx ts-node script/deploy.ts - Select the SOURCE chain: - 1: Avalanche testnet fuji - 2: Celo Testnet - - Enter the number for the SOURCE chain: 1 - - Select the TARGET chain: - 1: Avalanche testnet fuji - 2: Celo Testnet - - Enter the number for the TARGET chain: 2 - CrossChainSender Avalanche testnet fuji: 0x1Cac52a183D02F9002fdb37b13eC2fAB950d44E3 - CrossChainReceiver Celo Testnet: 0xD720BFF42a0960cfF1118454A907a44dB358f2b1 - - Registering CrossChainSender (0x1Cac52a183D02F9002fdb37b13eC2fAB950d44E3) as a valid sender in CrossChainReceiver (0xD720BFF42a0960cfF1118454A907a44dB358f2b1)... - - CrossChainSender registered as a valid sender on Celo Testnet - -
+ ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; -## Transfer Tokens Across Chains +// Extend the TokenSender contract inherited from TokenBase +contract CrossChainSender is TokenSender { + uint256 constant GAS_LIMIT = 250_000; + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} -### Quick Recap + // Calculate the estimated cost for multichain token transfer using + // the wormholeRelayer to get the delivery cost and add the message fee + function quoteCrossChainDeposit( + uint16 targetChain + ) public view returns (uint256 cost) { + uint256 deliveryCost; + (deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice( + targetChain, + 0, + GAS_LIMIT + ); -Up to this point, you've set up a new Solidity project using Foundry, developed two key contracts (`CrossChainSender` and `CrossChainReceiver`), and created a deployment script to deploy these contracts to different blockchain networks. The deployment script also saves the new contract addresses for easy reference. With everything in place, it's time to transfer tokens using the deployed contracts. + cost = deliveryCost + wormhole.messageFee(); + } -In this step, you'll write a script to transfer tokens across chains using the `CrossChainSender` and `CrossChainReceiver` contracts you deployed earlier. This script will interact with the contracts and facilitate the cross-chain token transfer. + // Send tokens and payload to the recipient on the target chain + function sendCrossChainDeposit( + uint16 targetChain, + address targetReceiver, + address recipient, + uint256 amount, + address token + ) public payable { + // Calculate the estimated cost for the multichain deposit + uint256 cost = quoteCrossChainDeposit(targetChain); + require( + msg.value == cost, + "msg.value must equal quoteCrossChainDeposit(targetChain)" + ); + // Transfer the tokens from the sender to this contract + IERC20(token).transferFrom(msg.sender, address(this), amount); + // Encode the recipient address into the payload + bytes memory payload = abi.encode(recipient); + // Initiate the multichain transfer using the wormholeRelayer + sendTokenWithPayloadToEvm( + targetChain, + targetReceiver, + payload, + 0, + GAS_LIMIT, + token, + amount + ); + } +} + ``` -### Transfer Script + This contract extends `TokenSender`, gaining access to its functionality. It initializes the contract with the required addresses, calculates estimated transfer costs, defines transfer parameters, and initiates the transfer using the `sendTokenWithPayloadToEvm` function from `WormholeRelayer`. -1. **Set up the transfer script** +2. Use the following example code to create `CrossChainReceiver.sol`: - 1. Create a new file named `transfer.ts` in the `/script` directory: + ```solidity title="CrossChainSender.sol" + // SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; - ```bash - touch script/transfer.ts - ``` +import "lib/wormhole-solidity-sdk/src/WormholeRelayerSDK.sol"; +import "lib/wormhole-solidity-sdk/src/interfaces/IERC20.sol"; - 2. Open the file. Start with the necessary imports, interfaces and configurations: +// Extend the TokenReceiver contract inherited from TokenBase +contract CrossChainReceiver is TokenReceiver { + // Initialize the contract with the Wormhole relayer, Token Bridge, + // and Wormhole Core Contract addresses + constructor( + address _wormholeRelayer, + address _tokenBridge, + address _wormhole + ) TokenBase(_wormholeRelayer, _tokenBridge, _wormhole) {} - ```typescript - import * as fs from 'fs'; -import * as path from 'path'; -import * as dotenv from 'dotenv'; -import readlineSync from 'readline-sync'; + // Receive the multichain payload and tokens + // Verify the transfer is from a registered sender + function receivePayloadAndTokens( + bytes memory payload, + TokenReceived[] memory receivedTokens, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 // deliveryHash + ) + internal + override + onlyWormholeRelayer + isRegisteredSender(sourceChain, sourceAddress) + { + // Ensure the payload is not empty and only has one token transfer + require(receivedTokens.length == 1, "Expected 1 token transfer"); -dotenv.config(); + // Decode the recipient address from the payload + address recipient = abi.decode(payload, (address)); -interface ChainConfig { - description: string; - chainId: number; - rpc: string; - tokenBridge: string; - wormholeRelayer: string; - wormhole: string; + // Transfer the received tokens to the intended recipient + IERC20(receivedTokens[0].tokenAddress).transfer( + recipient, + receivedTokens[0].amount + ); + } } + ``` -interface DeployedContracts { - [chainId: number]: { - networkName: string; - CrossChainSender?: string; - CrossChainReceiver?: string; - deployedAt: string; - }; -} - ``` + This contract extends `TokenReceiver`, gaining access to its functionality. It initializes the contract with the required addresses, receives the payload and tokens, verifies the transfer is from a registered sender, decodes the recipient address, and transfers the tokens to the recipient. - These imports include the essential libraries for interacting with Ethereum, handling file paths, loading environment variables, and managing user input. +3. Deploy the contracts using your preferred deployment method. Make sure you deploy `CrossChainSender.sol` to your desired source chain and `CrossChainReceiver.sol` to the target chain. Save the deployed contract addresses for each contract. You will need them for your transfer script. - 3. Load configuration and contracts: +## Use Contracts to Transfer USDC +1. Once your contracts are deployed, create a `transfer.ts` file to handle the multichain transfer logic: - ```typescript - const configPath = path.resolve(__dirname, '../deploy-config/config.json'); - return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; -} + ```bash + touch script/transfer.ts + ``` -function loadDeployedContracts(): DeployedContracts { - const contractsPath = path.resolve( - __dirname, - '../deploy-config/contracts.json' - ); - if ( - !fs.existsSync(contractsPath) || - fs.readFileSync(contractsPath, 'utf8').trim() === '' - ) { - console.error( - 'No contracts found. Please deploy contracts first before transferring tokens.' - ); - process.exit(1); - } - return JSON.parse(fs.readFileSync(contractsPath, 'utf8')); -} - ``` +2. Set up secure access to your wallets. This guide assumes you are loading your private key(s) from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. - These functions load the network and contract details that were saved during deployment. + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. - 4. Allow users to select source and target chains: +3. Open `transfer.ts` and add the following code: - Refer to the deployed contracts and create logic as desired. In our example, we made this process interactive, allowing users to select the source and target chains from all the historically deployed contracts. This interactive approach helps ensure the correct chains are selected for the token transfer. + ```typescript title="transfer.ts" + import { ethers } from 'ethers'; +import fs from 'fs'; +import path from 'path'; +import readlineSync from 'readline-sync'; +import { fileURLToPath } from 'url'; +import { wormhole, chainToChainId } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; - ```typescript - chainId: number; - networkName: string; -} { - const sourceOptions = Object.entries(deployedContracts).filter( - ([, contracts]) => contracts.CrossChainSender - ); +// Replace with your contract address and chain names +const AVALANCHE_SENDER_ADDRESS = 'INSERT_AVALANCHE_SENDER_CONTRACT_ADDRESS'; +const CELO_RECEIVER_ADDRESS = 'INSERT_CELO_RECEIVER_ADDRESS'; +const AVALANCHE_CHAIN_NAME = 'Avalanche'; +const CELO_CHAIN_NAME = 'Celo'; + +// Fetch the contract ABI from the local filesystem +// This example uses the `out` directory from a Foundry deployment +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const SENDER_ABI_PATH = path.resolve( + __dirname, + '../out/CrossChainSender.sol/CrossChainSender.json' +); - if (sourceOptions.length === 0) { - console.error('No source chains available with CrossChainSender deployed.'); - process.exit(1); - } +(async function () { + try { + console.log('Initializing Wormhole SDK...'); + const wh = await wormhole('Testnet', [evm]); + const sendChain = wh.getChain(AVALANCHE_CHAIN_NAME); + const rcvChain = wh.getChain(CELO_CHAIN_NAME); + + // The EVM_PRIVATE_KEY value must be loaded securely beforehand, + // for example via a keystore, secrets manager, or environment variables + // (not recommended) + const EVM_PRIVATE_KEY = EVM_PRIVATE_KEY!; + if (!EVM_PRIVATE_KEY) { + console.error('EVM_PRIVATE_KEY is not set in your .env file.'); + process.exit(1); + } - console.log('\nSelect the source chain:'); - sourceOptions.forEach(([chainId, contracts], index) => { - console.log(`${index + 1}: ${contracts.networkName}`); - }); + // Get the RPC URL or Provider from the SDK + const sourceRpcOrProvider = await sendChain.getRpc(); + let sourceProvider: ethers.JsonRpcProvider; + if ( + sourceRpcOrProvider && + typeof (sourceRpcOrProvider as any).getBlockNumber === 'function' + ) { + sourceProvider = sourceRpcOrProvider as ethers.JsonRpcProvider; + } else if (typeof sourceRpcOrProvider === 'string') { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider); + } else if ( + Array.isArray(sourceRpcOrProvider) && + typeof sourceRpcOrProvider[0] === 'string' + ) { + sourceProvider = new ethers.JsonRpcProvider(sourceRpcOrProvider[0]); + } else { + console.error( + 'Could not get a valid RPC URL or Provider from SDK:', + sourceRpcOrProvider + ); + process.exit(1); + } - const selectedIndex = - readlineSync.questionInt(`\nEnter the number for the source chain: `) - 1; - return { - chainId: Number(sourceOptions[selectedIndex][0]), - networkName: sourceOptions[selectedIndex][1].networkName, - }; -} + // Create the wallet using the provider and private key + const sourceWallet = new ethers.Wallet(EVM_PRIVATE_KEY, sourceProvider); -function selectTargetChain(deployedContracts: DeployedContracts): { - chainId: number; - networkName: string; -} { - const targetOptions = Object.entries(deployedContracts).filter( - ([, contracts]) => contracts.CrossChainReceiver - ); + // Load the sender contract ABI + if (!fs.existsSync(SENDER_ABI_PATH)) { + console.error(`ABI file not found at ${SENDER_ABI_PATH}`); + process.exit(1); + } + const CrossChainSenderArtifact = JSON.parse( + fs.readFileSync(SENDER_ABI_PATH, 'utf8') + ); + const senderAbi = CrossChainSenderArtifact.abi; - if (targetOptions.length === 0) { - console.error( - 'No target chains available with CrossChainReceiver deployed.' + // Create new sender contract instance + const senderContract = new ethers.Contract( + AVALANCHE_SENDER_ADDRESS, + senderAbi, + sourceWallet ); - process.exit(1); - } - console.log('\nSelect the target chain:'); - targetOptions.forEach(([chainId, contracts], index) => { - console.log(`${index + 1}: ${contracts.networkName}`); - }); + // Get user input for token transfer parameters + const tokenAddress = readlineSync.question( + 'Enter the (ERC20) token contract address on Avalanche: ' + ); + const recipientAddress = readlineSync.question( + 'Enter the recipient address on Celo: ' + ); + const amountStr = readlineSync.question( + 'Enter the amount of tokens to transfer: ' + ); - const selectedIndex = - readlineSync.questionInt(`\nEnter the number for the target chain: `) - 1; - return { - chainId: Number(targetOptions[selectedIndex][0]), - networkName: targetOptions[selectedIndex][1].networkName, - }; -} - ``` + // Approve sending tokens from the source wallet to the sender contract + const tokenContract = new ethers.Contract( + tokenAddress, + [ + 'function decimals() view returns (uint8)', + 'function approve(address spender, uint256 amount) public returns (bool)', + 'function allowance(address owner, address spender) view returns (uint256)', + ], + sourceWallet + ); -2. **Implement the token transfer logic** + // Convert the amount to the correct units based on token decimals + const decimals = Number(await tokenContract.decimals()); + const amountToTransfer = ethers.parseUnits(amountStr, decimals); + + // Get a transfer cost quote + const targetChainId = chainToChainId(rcvChain.chain); + const cost = await senderContract.quoteCrossChainDeposit(targetChainId); + // Approve the sender contract to spend the tokens + const approveTx = await tokenContract.approve( + AVALANCHE_SENDER_ADDRESS, + amountToTransfer + ); + await approveTx.wait(); - 1. Start the `main` function: - - ```typescript - const chains = loadConfig(); - const deployedContracts = loadDeployedContracts(); + // Initiate the transfer + console.log( + `Initiating cross-chain transfer to ${CELO_RECEIVER_ADDRESS} on ${rcvChain.chain}...` + ); + const transferTx = await senderContract.sendCrossChainDeposit( + targetChainId, + CELO_RECEIVER_ADDRESS, + recipientAddress, + amountToTransfer, + tokenAddress, + { value: cost } + ); + console.log(`Transfer transaction sent: ${transferTx.hash}`); + await transferTx.wait(); + console.log(`✅ Transfer initiated successfully!`); + } catch (error) { + console.error('An error occurred:', error); + process.exit(1); + } - // Select the source chain (only show chains with CrossChainSender deployed) - const { chainId: sourceChainId, networkName: sourceNetworkName } = - selectSourceChain(deployedContracts); - const sourceChain = chains.find((chain) => chain.chainId === sourceChainId)!; + process.exit(0); +})(); + ``` - // Select the target chain (only show chains with CrossChainReceiver deployed) - const { chainId: targetChainId, networkName: targetNetworkName } = - selectTargetChain(deployedContracts); - const targetChain = chains.find((chain) => chain.chainId === targetChainId)!; + This script defines the sender and receiver contract addresses, fetches the necessary ABI information, creates a connected signer, converts decimals, calculates the estimated transfer cost, and initiates the token transfer. - // Set up providers and wallets - const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); +3. Run the script using the following command: - // Load the ABI from the JSON file (use the compiled ABI from Forge or Hardhat) - const CrossChainSenderArtifact = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainSender.sol/CrossChainSender.json' - ), - 'utf8' - ) - ); + ```bash + npx tsx script/transfer.ts + ``` - const abi = CrossChainSenderArtifact.abi; +4. Follow the prompts in the terminal. This example uses Avalanche Fuji as the source chain, Celo Testnet as the target, [Avalanche Fuji testnet USDC](https://developers.circle.com/stablecoins/usdc-on-test-networks){target=\_blank}, and a developer wallet as the recipient address. You will see terminal output similar to the following: - // Create the contract instance using the full ABI - const CrossChainSender = new ethers.Contract( - deployedContracts[sourceChainId].CrossChainSender!, - abi, - wallet - ); - ``` - - The `main` function is where the token transfer logic will reside. It loads the chain and contract details, sets up the wallet and provider, and loads the `CrossChainSender` contract. +
+npx tsx script/transfer.ts +Initializing Wormhole SDK... +Enter the (ERC20) token contract address on Avalanche: 0x5425890298aed601595a70ab815c96711a31bc65 +Enter the recipient address on Celo: 0xCD8Bcd9A793a7381b3C66C763c3f463f70De4e12 +Initiating cross-chain transfer to 0xff97a7141833fbe829249d4e8952A8e73a4a2fbd on Celo... +Transfer transaction sent: 0x2d819aadf88309eb19f59a510aba1f2892b54487f9e287feadd150181a28f771 +✅ Transfer initiated successfully! + +
- 2. Ask the user for token transfer details: +Congratulations! You've successfully created and deployed Wormhole Solidity SDK-based smart contracts and used them to send testnet USDC across blockchains. Consider the following options to build upon what you've accomplished. - You'll now ask the user for the token contract address, the recipient address on the target chain, and the amount of tokens to transfer. +## Next Steps - ```typescript - 'Enter the token contract address: ' - ); - const recipientAddress = readlineSync.question( - 'Enter the recipient address on the target chain: ' - ); +- [**Get Started with Messaging**](/docs/products/messaging/get-started/): Send a message across blockchains using the Wormhole TypeScript SDK to eliminate smart contract development and auditing overhead. +--- END CONTENT --- - // Get the token contract - const tokenContractDecimals = new ethers.Contract( - tokenAddress, - [ - 'function decimals() view returns (uint8)', - 'function approve(address spender, uint256 amount) public returns (bool)', - ], - wallet - ); +Doc-Content: https://wormhole.com/docs/tools/solidity-sdk/sdk-reference/ +--- BEGIN CONTENT --- +--- +title: Solidity SDK +description: How to use the Wormhole Solidity SDK for cross-chain messaging, token transfers, and integrating decentralized applications on EVM-compatible blockchains. +categories: Solidity-SDK +--- - // Fetch the token decimals - const decimals = await tokenContractDecimals.decimals(); +# Solidity SDK - // Get the amount from the user, then parse it according to the token's decimals - const amount = ethers.parseUnits( - readlineSync.question('Enter the amount of tokens to transfer: '), - decimals - ); - ``` +This page covers all you need to know about the functionality offered through the Wormhole Solidity SDK. - This section of the script prompts the user for the token contract address and the recipient's address, fetches the token's decimal value, and parses the amount accordingly. +
- 3. Initiate the transfer: +- :octicons-download-16:{ .lg .middle } **Installation** - Finally, initiate the cross-chain transfer and log the details. + --- - ```typescript - // Approve the CrossChainSender contract to transfer tokens on behalf of the user - const tokenContract = new ethers.Contract( - tokenAddress, - ['function approve(address spender, uint256 amount) public returns (bool)'], - wallet - ); + Find installation instructions using Foundry and Forge to pull the necessary libraries into your project. - const approveTx = await tokenContract.approve( - deployedContracts[sourceChainId].CrossChainSender!, - amount - ); - await approveTx.wait(); - console.log(`Approved tokens for cross-chain transfer.`); + [:custom-arrow: Install the SDK](/docs/tools/solidity-sdk/get-started/#installation) - // Initiate the cross-chain transfer - const transferTx = await CrossChainSender.sendCrossChainDeposit( - targetChainId, - deployedContracts[targetChainId].CrossChainReceiver!, - recipientAddress, - amount, - tokenAddress, - { value: cost } // Attach the necessary fee for cross-chain transfer - ); - await transferTx.wait(); - console.log( - `Transfer initiated from ${sourceNetworkName} to ${targetNetworkName}. Transaction Hash: ${transferTx.hash}` - ); -} - ``` +- :octicons-download-16:{ .lg .middle } **Source Code** - This part of the script first approves the token transfer, then initiates the cross-chain transfer using the `CrossChainSender` contract, and finally logs the transaction hash for the user to track. + --- - 4. Finalize the script: + Want to go straight to the source? Check out the Solidity SDK GitHub repository. - ```typescript - console.error(error); - process.exit(1); -}); - ``` + [:custom-arrow: View GitHub Repository](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} - This section finalizes the script by calling the `main` function and handling any errors that may occur during the token transfer process. +
-You can find the full code for the `transfer.ts` file below: +## Key Considerations -??? code "transfer.ts" +Before deploying applications using the Wormhole Solidity SDK, keep these considerations in mind: - ```solidity - import { ethers } from 'ethers'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as dotenv from 'dotenv'; -import readlineSync from 'readline-sync'; + - **IERC-20 remapping** - the SDK provides a remapping mechanism to handle potential conflicts between different implementations of IERC20, ensuring seamless integration with other libraries + - **Testing** - given the cross-chain dependencies, testing all integrations is critical to avoid issues in production environments -dotenv.config(); +## Concepts and Components -interface ChainConfig { - description: string; - chainId: number; - rpc: string; - tokenBridge: string; - wormholeRelayer: string; - wormhole: string; -} +The Wormhole Solidity SDK consists of key components that streamline cross-chain communication, allowing developers to securely and efficiently interact with Wormhole’s infrastructure. Below are the critical concepts and contracts you'll encounter when working with the SDK. -interface DeployedContracts { - [chainId: number]: { - networkName: string; - CrossChainSender?: string; - CrossChainReceiver?: string; - deployedAt: string; - }; -} +### Cross-Chain Messaging with the Wormhole Relayer SDK -function loadConfig(): ChainConfig[] { - const configPath = path.resolve(__dirname, '../deploy-config/config.json'); - return JSON.parse(fs.readFileSync(configPath, 'utf8')).chains; -} +The [`WormholeRelayerSDK.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol){target=\_blank} contract simplifies cross-chain messaging and asset transfers by integrating several necessary modules, including the Wormhole relayer. By automating message delivery between chains, the Wormhole relayer removes the need for developers to manage relayer infrastructure or handle gas on the target chain. Delivery providers handle the message payload, ensuring secure and efficient communication. -function loadDeployedContracts(): DeployedContracts { - const contractsPath = path.resolve( - __dirname, - '../deploy-config/contracts.json' - ); - if ( - !fs.existsSync(contractsPath) || - fs.readFileSync(contractsPath, 'utf8').trim() === '' - ) { - console.error( - 'No contracts found. Please deploy contracts first before transferring tokens.' - ); - process.exit(1); - } - return JSON.parse(fs.readFileSync(contractsPath, 'utf8')); -} +You can refer to the [Wormhole relayer documentation](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank} for more details. -function selectSourceChain(deployedContracts: DeployedContracts): { - chainId: number; - networkName: string; -} { - const sourceOptions = Object.entries(deployedContracts).filter( - ([, contracts]) => contracts.CrossChainSender - ); +Key modules in the SDK include: - if (sourceOptions.length === 0) { - console.error('No source chains available with CrossChainSender deployed.'); - process.exit(1); - } + - **`Base.sol`** - the core module for cross-chain messaging. It provides utility functions like `onlyWormholeRelayer()` and `setRegisteredSender()`, ensuring that only messages from trusted relayers are processed - console.log('\nSelect the source chain:'); - sourceOptions.forEach(([chainId, contracts], index) => { - console.log(`${index + 1}: ${contracts.networkName}`); - }); + - **`TokenBase.sol`** - this module extends the base messaging functionality to support cross-chain token transfers. It includes utilities for securely sending and receiving tokens between EVM-compatible chains - const selectedIndex = - readlineSync.questionInt(`\nEnter the number for the source chain: `) - 1; - return { - chainId: Number(sourceOptions[selectedIndex][0]), - networkName: sourceOptions[selectedIndex][1].networkName, - }; -} + - **`CCTPBase.sol`** - designed for Circle’s Cross-Chain Transfer Protocol, this module manages asset transfers such as USDC between chains. It includes functionalities for both sending and receiving CCTP-based assets -function selectTargetChain(deployedContracts: DeployedContracts): { - chainId: number; - networkName: string; -} { - const targetOptions = Object.entries(deployedContracts).filter( - ([, contracts]) => contracts.CrossChainReceiver - ); + - **`CCTPAndTokenBase.sol`** - a combined module that supports token and CCTP-based asset transfers in a single implementation. This module simplifies development for applications needing to handle both types of transfers - if (targetOptions.length === 0) { - console.error( - 'No target chains available with CrossChainReceiver deployed.' - ); - process.exit(1); - } +The Wormhole Solidity SDK offers a unified framework for cross-chain communication. Developers can select specific modules based on their application’s requirements, whether for messaging, token transfers, or CCTP. Each module includes built-in security measures, ensuring that only authorized senders or relayers are accepted, thereby protecting the application from unauthorized interactions. - console.log('\nSelect the target chain:'); - targetOptions.forEach(([chainId, contracts], index) => { - console.log(`${index + 1}: ${contracts.networkName}`); - }); +Please refer to the complete `WormholeRelayerSDK.sol` file below for further details. - const selectedIndex = - readlineSync.questionInt(`\nEnter the number for the target chain: `) - 1; - return { - chainId: Number(targetOptions[selectedIndex][0]), - networkName: targetOptions[selectedIndex][1].networkName, - }; -} +???- code "`WormholeRelayerSDK.sol`" + ```solidity + // SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.19; -async function main() { - const chains = loadConfig(); - const deployedContracts = loadDeployedContracts(); +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/constants/Chains.sol"; +import "wormhole-sdk/Utils.sol"; - // Select the source chain (only show chains with CrossChainSender deployed) - const { chainId: sourceChainId, networkName: sourceNetworkName } = - selectSourceChain(deployedContracts); - const sourceChain = chains.find((chain) => chain.chainId === sourceChainId)!; +import {Base} from "wormhole-sdk/WormholeRelayer/Base.sol"; +import {TokenBase, TokenReceiver, TokenSender} from "wormhole-sdk/WormholeRelayer/TokenBase.sol"; +import {CCTPBase, CCTPReceiver, CCTPSender} from "wormhole-sdk/WormholeRelayer/CCTPBase.sol"; +import {CCTPAndTokenBase, CCTPAndTokenReceiver, CCTPAndTokenSender} from "wormhole-sdk/WormholeRelayer/CCTPAndTokenBase.sol"; + ``` - // Select the target chain (only show chains with CrossChainReceiver deployed) - const { chainId: targetChainId, networkName: targetNetworkName } = - selectTargetChain(deployedContracts); - const targetChain = chains.find((chain) => chain.chainId === targetChainId)!; +### Base Contract Overview - // Set up providers and wallets - const sourceProvider = new ethers.JsonRpcProvider(sourceChain.rpc); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, sourceProvider); +The [`Base.sol`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayer/Base.sol){target=\_blank} contract is a core part of the Wormhole Solidity SDK, providing essential helper functions and modifiers for managing cross-chain messages securely via the Wormhole Relayer. It handles sender registration and message validation, ensuring only authorized senders from specific chains can send messages. - // Load the ABI from the JSON file (use the compiled ABI from Forge or Hardhat) - const CrossChainSenderArtifact = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - '../out/CrossChainSender.sol/CrossChainSender.json' - ), - 'utf8' - ) - ); + - **`onlyWormholeRelayer()`** - a modifier that ensures only authorized messages from the Wormhole relayer contract are processed, restricting access to certain functions - const abi = CrossChainSenderArtifact.abi; + ```solidity + require( + msg.sender == address(wormholeRelayer), + "Msg.sender is not Wormhole Relayer" + ); + _; + } + ``` - // Create the contract instance using the full ABI - const CrossChainSender = new ethers.Contract( - deployedContracts[sourceChainId].CrossChainSender!, - abi, - wallet - ); + - **`setRegisteredSender()`** - restricts message acceptance to a registered sender from a specific chain, ensuring messages are only processed from trusted sources - // Display the selected chains - console.log( - `\nInitiating transfer from ${sourceNetworkName} to ${targetNetworkName}.` - ); + ```solidity + uint16 sourceChain, + bytes32 sourceAddress + ) public { + require( + msg.sender == registrationOwner, + "Not allowed to set registered sender" + ); + registeredSenders[sourceChain] = sourceAddress; + } + ``` - // Ask the user for token transfer details - const tokenAddress = readlineSync.question( - 'Enter the token contract address: ' - ); - const recipientAddress = readlineSync.question( - 'Enter the recipient address on the target chain: ' - ); +These security measures ensure messages come from the correct source and are processed securely. Please refer to the complete `Base.sol` contract below for further details. - // Get the token contract - const tokenContractDecimals = new ethers.Contract( - tokenAddress, - [ - 'function decimals() view returns (uint8)', - 'function approve(address spender, uint256 amount) public returns (bool)', - ], - wallet - ); +???- code "`Base.sol`" + ```solidity + // SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.19; - // Fetch the token decimals - const decimals = await tokenContractDecimals.decimals(); +import "wormhole-sdk/interfaces/IWormholeReceiver.sol"; +import "wormhole-sdk/interfaces/IWormholeRelayer.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; +import "wormhole-sdk/Utils.sol"; - // Get the amount from the user, then parse it according to the token's decimals - const amount = ethers.parseUnits( - readlineSync.question('Enter the amount of tokens to transfer: '), - decimals - ); +abstract contract Base { + IWormholeRelayer public immutable wormholeRelayer; + IWormhole public immutable wormhole; - // Calculate the cross-chain transfer cost - const cost = await CrossChainSender.quoteCrossChainDeposit(targetChainId); + address registrationOwner; + mapping(uint16 => bytes32) registeredSenders; - // Approve the CrossChainSender contract to transfer tokens on behalf of the user - const tokenContract = new ethers.Contract( - tokenAddress, - ['function approve(address spender, uint256 amount) public returns (bool)'], - wallet - ); + constructor(address _wormholeRelayer, address _wormhole) { + wormholeRelayer = IWormholeRelayer(_wormholeRelayer); + wormhole = IWormhole(_wormhole); + registrationOwner = msg.sender; + } - const approveTx = await tokenContract.approve( - deployedContracts[sourceChainId].CrossChainSender!, - amount - ); - await approveTx.wait(); - console.log(`Approved tokens for cross-chain transfer.`); + modifier onlyWormholeRelayer() { + require( + msg.sender == address(wormholeRelayer), + "Msg.sender is not Wormhole Relayer" + ); + _; + } - // Initiate the cross-chain transfer - const transferTx = await CrossChainSender.sendCrossChainDeposit( - targetChainId, - deployedContracts[targetChainId].CrossChainReceiver!, - recipientAddress, - amount, - tokenAddress, - { value: cost } // Attach the necessary fee for cross-chain transfer - ); - await transferTx.wait(); - console.log( - `Transfer initiated from ${sourceNetworkName} to ${targetNetworkName}. Transaction Hash: ${transferTx.hash}` - ); -} + modifier isRegisteredSender(uint16 sourceChain, bytes32 sourceAddress) { + require( + registeredSenders[sourceChain] == sourceAddress, + "Not registered sender" + ); + _; + } -main().catch((error) => { - console.error(error); - process.exit(1); -}); + /** + * Sets the registered address for 'sourceChain' to 'sourceAddress' + * So that for messages from 'sourceChain', only ones from 'sourceAddress' are valid + * + * Assumes only one sender per chain is valid + * Sender is the address that called 'send' on the Wormhole Relayer contract on the source chain) + */ + function setRegisteredSender( + uint16 sourceChain, + bytes32 sourceAddress + ) public { + require( + msg.sender == registrationOwner, + "Not allowed to set registered sender" + ); + registeredSenders[sourceChain] = sourceAddress; + } +} ``` -### Transfer Tokens - -Now that your transfer script is ready, it’s time to execute it and perform a cross-chain token transfer. +### Interface for Cross-Chain Messages -1. **Run the transfer script** +The Wormhole Solidity SDK interacts with the Wormhole relayer for sending and receiving messages across EVM-compatible chains. The [`IWormholeRelayer`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/interfaces/IWormholeRelayer.sol){target=\_blank} includes several interfaces that are central to cross-chain communication, enabling secure and efficient message delivery. - Open your terminal and run the transfer script: +For detailed information on how to implement these interfaces, refer to the [Wormhole Relayer Interfaces documentation](/docs/products/messaging/guides/wormhole-relayers/#wormhole-relayer-interfaces){target=\_blank}. This section covers: - ```bash - npx ts-node script/transfer.ts - ``` + - **`IWormholeRelayer`** – methods for sending cross-chain messages, VAAs, and token transfers + - **`IWormholeReceiver`** – the required implementation for receiving cross-chain messages + - **`quoteEVMDeliveryPrice()`** – how to estimate gas and fees for cross-chain transactions - This command will start the script, prompting you to select the source and target chains, input the token address, recipient address, and the amount of tokens to transfer. +These interfaces reduce the complexity of cross-chain dApp development by abstracting away the details of relayer infrastructure, ensuring that message delivery is handled efficiently. -2. **Follow the prompts** - the script will guide you through selecting the source and target chains and entering the necessary details for the token transfer. Once you provide all the required information, the script will initiate the token transfer +### Advanced Concepts -3. **Verify the transaction** - after running the script, you should see a confirmation message with the transaction hash. You can use this transaction hash to check the transfer status on the respective blockchain explorers +For developers interested in exploring additional advanced topics, the following sections provide insights into key aspects of the SDK’s functionality. -You can verify the transaction on the [Wormhole Explorer](https://wormholescan.io/){target=\_balnk} using the link provided in the terminal output. This explorer also offers the option to add the transferred token to your MetaMask wallet automatically. +???- note "Error Handling and Reverts" + The SDK defines several custom errors to help developers handle common issues like incorrect gas fees, invalid senders, and more. For example, `InvalidMsgValue` is thrown when the message value for a relayed message is erroneous. -If you followed the logic provided in the `transfer.ts` file above, your terminal output should look something like this: + ```solidity + error InvalidMsgValue(uint256 msgValue, uint256 totalFee); + ``` -
-npx ts-node transfer.ts - > cross-chain-token-transfer@1.0.0 transfer - > npx ts-node script/transfer.ts - - Select the source chain: - 1: Avalanche testnet fuji - 2: Celo Testnet - - Enter the number for the SOURCE chain: 1 - - Select the target chain: - 1: Avalanche testnet fuji - 2: Celo Testnet - - Enter the number for the TARGET chain: 2 - - Initiating transfer from Avalanche testnet fuji to Celo Testnet - Enter the token contract address: 0x5425890298aed601595a70ab815c96711a31bc65 - Enter the recipient address on the target chain: INSERT_YOUR_WALLET_ADDRESS - Enter the amount of tokens to transfer: 2 - Approved tokens for cross-chain transfer. - Transfer initiated from Avalanche testnet fuji to Celo Testnet. Transaction Hash: 0x4a923975d955c1f226a1c2f61a1a0fa1ab1a9e229dc29ceaeadf8ef40acd071f - -
+## Usage -!!! note - In this example, we demonstrated a token transfer from the Avalanche Fuji Testnet to the Celo Alfajores Testnet. We sent two units of USDC Testnet tokens using the token contract address `0x5425890298aed601595a70ab815c96711a31bc65`. You can replace these details with those relevant to your project or use the same for testing purposes. +This section covers cross-chain messaging and token transfers and shows how to use the Wormhole Solidity SDK in real-world scenarios. -## Resources +### Send a Cross-Chain Message -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in the [Cross-Chain Token Transfers GitHub repository](https://github.com/wormhole-foundation/demo-cross-chain-token-transfer){target=\_blank}. The repository includes all the scripts, contracts, and configurations needed to deploy and transfer tokens across chains using the Wormhole protocol. +To send a cross-chain message, inherit from the base contract provided by the SDK and use its helper methods to define your message and sender address. Here’s a basic example: -## Conclusion +```solidity +pragma solidity ^0.8.19; -Congratulations! You've successfully built and deployed a cross-chain token transfer system using Solidity and the Wormhole protocol. You've learned how to: +import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/Base.sol"; - - Set up a new Solidity project using Foundry - - Develop smart contracts to send and receive tokens across chains - - Write deployment scripts to manage and deploy contracts on different networks ---- END CONTENT --- +contract CrossChainSender is Base { + constructor( + address _wormholeRelayer, + address _wormhole + ) Base(_wormholeRelayer, _wormhole) {} -Doc-Content: https://wormhole.com/docs/tutorials/solidity-sdk/ ---- BEGIN CONTENT --- ---- -title: Solidity SDK Tutorials -description: Master cross-chain smart contracts with Wormhole's Solidity SDK. Learn messaging, token transfers, and secure, scalable dApp deployments across blockchains. ---- + function sendMessage( + bytes memory message, + uint16 targetChain, + bytes32 targetAddress + ) external payable { + // Register sender and send message through WormholeRelayer + setRegisteredSender(targetChain, msg.sender); + onlyWormholeRelayer().sendPayloadToEvm( + targetChain, + address(targetAddress), + message, + 0, + 500_000 + ); + } +} +``` -# Solidity SDK +This contract extends `Base.sol` and allows sending cross-chain messages securely using the `WormholeRelayer`. -Expand the reach of your decentralized applications by building smart contracts that can communicate across multiple blockchains. Through these tutorials, you’ll learn to create robust cross-chain contracts, enabling your dApps to tap into global liquidity, diverse functionalities, and a broader user base. +### Send Tokens Across Chains -## Tutorials +The SDK enables seamless token transfers between EVM-compatible chains in addition to sending messages. To facilitate cross-chain token transfers, you can extend the SDK's `TokenSender` and `TokenReceiver` base contracts. -
+```solidity +pragma solidity ^0.8.19; -- :octicons-repo-16:{ .lg .middle } **Create Cross-Chain Messaging Contracts** +import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/TokenBase.sol"; - --- +contract CrossChainTokenSender is TokenSender { + constructor( + address _wormholeRelayer, + address _wormhole + ) TokenSender(_wormholeRelayer, _wormhole) {} - Learn how to build and deploy smart contracts that communicate seamlessly across multiple blockchains. This tutorial walks you through using Wormhole's Solidity SDK to send and receive messages between Avalanche Fuji and Celo Alfajores, helping you master emitter validation, relayer usage, and cross-chain cost management. + function sendToken( + address token, + uint256 amount, + uint16 targetChain, + bytes32 targetAddress + ) external payable { + // Send tokens across chains + transferTokenToTarget(token, amount, targetChain, targetAddress); + } +} +``` - [:custom-arrow: Start building](/docs/tutorials/solidity-sdk/cross-chain-contracts/) +In this example, `TokenSender` initiates a token transfer to another chain. The SDK’s built-in utilities securely handle token transfers, ensuring proper VAAs are generated and processed. -- :octicons-repo-16:{ .lg .middle } **Create Cross-Chain Token Transfer Contracts** +### Receive Tokens Across Chains - --- +To receive tokens on the target chain, implement a contract that inherits from `TokenReceiver` and overrides the `receiveWormholeMessages` function. - Discover how to create a fully functional cross-chain token transfer system using Wormhole's Solidity SDK. This tutorial guides you through token attestation, contract deployment, and secure transfers of ERC-20 tokens between test networks. By the end, you’ll know how to tap into global liquidity and enrich your dApps with seamless multi-chain asset movement. +```solidity +pragma solidity ^0.8.19; - [:custom-arrow: Start building](/docs/tutorials/solidity-sdk/cross-chain-token-contracts/) +import "@wormhole-foundation/wormhole-solidity-sdk/src/WormholeRelayer/TokenBase.sol"; -
+contract CrossChainTokenReceiver is TokenReceiver { + constructor( + address _wormholeRelayer, + address _wormhole + ) TokenReceiver(_wormholeRelayer, _wormhole) {} -## Additional Resources + // Function to handle received tokens from another chain + function receiveWormholeMessages( + bytes memory payload, + bytes[] memory additionalMessages, + bytes32 sourceAddress, + uint16 sourceChain, + bytes32 deliveryHash + ) external payable override { + // Process the received tokens here + receiveTokens(payload); + } +} +``` -
+In this example, `TokenReceiver` allows the contract to handle tokens sent from the source chain. Once the cross-chain message is received, the `receiveWormholeMessages` function processes the incoming tokens. Always validate the message's authenticity and source. -- :octicons-book-16:{ .lg .middle } **Core Contracts** +!!! note + Always verify the source of incoming messages and tokens to prevent unauthorized access to your contract. Please refer to the [Emitter Verification](/docs/products/messaging/guides/core-contracts/#validating-the-emitter/){target=\_blank} section for more details. - --- +## Testing Environment - Dive deeper into Wormhole’s foundational concepts for cross-chain contracts. Discover how messaging, guardians, and VAAs work together to enable secure, scalable dApps. +The SDK includes built-in support for Forge-based testing, which allows you to test your cross-chain applications locally before deploying them to production. Testing with the same Solidity compiler version and configuration you plan to use in production is highly recommended to catch any potential issues early. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) +For a detailed example, check out the below repositories: -
+ - [Cross chain messaging](/docs/products/messaging/tutorials/cross-chain-contracts/){target=\_blank} + - [Cross chain token transfer](/docs/products/messaging/tutorials/cross-chain-token-contracts/){target=\_blank} --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/typescript-sdk/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/get-started/ --- BEGIN CONTENT --- --- -title: Wormhole SDK Tutorials -description: Master the Wormhole SDK. Build robust cross-chain dApps with messaging, token bridging, and governance across multiple networks. +title: Get Started with the TypeScript SDK +description: Follow this guide to install the Wormhole TypeScript SDK, initialize a Wormhole instance, and add the platforms your integration supports. +categories: Typescript-SDK --- -# Wormhole SDK +# Get Started with the TypeScript SDK -The Wormhole SDK provides the essential building blocks for creating robust cross-chain applications. With its developer-friendly libraries, tools, and interfaces, you can quickly integrate Wormhole’s messaging, token transfer, and governance functionalities into your projects. Whether you’re building a simple cross-chain dApp or architecting a complex multi-chain ecosystem, these tutorials will guide you through mastering the SDK and unlocking the full potential of Wormhole’s infrastructure. +## Introduction -## Tutorials +The Wormhole TypeScript SDK provides a unified, type-safe interface for building cross-chain applications. It is a foundational toolkit that supports interaction with core Wormhole protocols, including Native Token Transfers, Token Bridge, CCTP, and Settlement, giving developers a consistent API across multiple chains. -
+This guide helps you install the SDK, initialize a `Wormhole` instance to support your desired network and blockchain platforms, and return chain-specific information to verify successful initialization. -- :octicons-repo-16:{ .lg .middle } **Transfer USDC via CCTP** +If you want to build more advanced integrations, such as token transfers using the Token Bridge or CCTP Bridge, skip ahead to [Next Steps](#next-steps). - --- +## Install the SDK - Learn how to move native USDC across chains using Circle’s CCTP and Wormhole’s TypeScript SDK. This tutorial shows you how to streamline transfers with automated attestation and finalization or take complete control with manual steps. Gain the skills to handle seamless USDC bridging, optimize user experience, and improve the reliability of your cross-chain applications. +To install the Wormhole TypeScript SDK, use the following command: - [:custom-arrow: Start building](/docs/tutorials/typescript-sdk/usdc-via-cctp/) +```bash +npm install @wormhole-foundation/sdk +``` -- :octicons-repo-16:{ .lg .middle } **Transfer Tokens via the Token Bridge** +This package combines all the individual packages to make setup easier. - --- +You can choose to install a specific set of packages as needed. For example, to install EVM-specific utilities, you can run: - Learn how to build a versatile cross-chain token transfer application using Wormhole’s TypeScript SDK. This tutorial walks you through leveraging the Token Bridge to securely and efficiently move assets between EVM and non-EVM chains. By the end, you’ll understand how to transfer tokens between networks like Ethereum, Solana, Sui, and beyond, opening the door to an interconnected blockchain ecosystem. +```bash +npm install @wormhole-foundation/sdk-evm +``` - [:custom-arrow: Start building](/docs/tutorials/typescript-sdk/tokens-via-token-bridge/) +??? example "Complete list of individually published packages" -
+ Platform-Specific Packages -## Additional Resources + - `@wormhole-foundation/sdk-evm` + - `@wormhole-foundation/sdk-solana` + - `@wormhole-foundation/sdk-algorand` + - `@wormhole-foundation/sdk-aptos` + - `@wormhole-foundation/sdk-cosmwasm` + - `@wormhole-foundation/sdk-sui` -
+ --- -- :octicons-tools-16:{ .lg .middle } **Wormhole SDK Documentation** + Protocol-Specific Packages - --- + - Core Protocol + - `@wormhole-foundation/sdk-evm-core` + - `@wormhole-foundation/sdk-solana-core` + - `@wormhole-foundation/sdk-algorand-core` + - `@wormhole-foundation/sdk-aptos-core` + - `@wormhole-foundation/sdk-cosmwasm-core` + - `@wormhole-foundation/sdk-sui-core` - Learn to build cross-chain dApps using the Wormhole SDK. Access detailed guides, reference code, and best practices for robust application development. + - Token Bridge + - `@wormhole-foundation/sdk-evm-tokenbridge` + - `@wormhole-foundation/sdk-solana-tokenbridge` + - `@wormhole-foundation/sdk-algorand-tokenbridge` + - `@wormhole-foundation/sdk-aptos-tokenbridge` + - `@wormhole-foundation/sdk-cosmwasm-tokenbridge` + - `@wormhole-foundation/sdk-sui-tokenbridge` - [:custom-arrow: Learn more](/docs/build/toolkit/typescript-sdk/) + - CCTP + - `@wormhole-foundation/sdk-evm-cctp` + - `@wormhole-foundation/sdk-solana-cctp` + - `@wormhole-foundation/sdk-aptos-cctp` + - `@wormhole-foundation/sdk-sui-cctp` -
---- END CONTENT --- + - Other Protocols + - `@wormhole-foundation/sdk-evm-portico` + - `@wormhole-foundation/sdk-evm-tbtc` + - `@wormhole-foundation/sdk-solana-tbtc` -Doc-Content: https://wormhole.com/docs/tutorials/typescript-sdk/tokens-via-token-bridge/ ---- BEGIN CONTENT --- ---- -title: Transfer Tokens via Token Bridge Tutorial -description: Learn to build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains ---- + --- -# Transfer Tokens via the Token Bridge + Utility Packages + + - `@wormhole-foundation/sdk-base` + - `@wormhole-foundation/sdk-definitions` + - `@wormhole-foundation/sdk-connect` -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-ts-sdk/){target=\_blank} -## Introduction +## Initialize the SDK -This tutorial guides you through building a cross-chain token transfer application using the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and its [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} method. The Token Bridge method enables secure and efficient cross-chain asset transfers across different blockchain networks, allowing users to move tokens seamlessly. +Getting your integration started is simple. First, import Wormhole: -By leveraging Wormhole’s Token Bridge, this guide shows you how to build an application that supports multiple transfer types: +```ts +import { wormhole } from '@wormhole-foundation/sdk'; - - EVM to EVM (e.g., Ethereum to Avalanche) - - EVM to non-EVM chains (e.g., Ethereum to Solana) - - Non-EVM to EVM chains (e.g., Sui to Avalanche) - - Non-EVM to non-EVM chains (e.g., Solana to Sui) +import { Wormhole, amount, signSendWait } from '@wormhole-foundation/sdk'; +import algorand from '@wormhole-foundation/sdk/algorand'; +import aptos from '@wormhole-foundation/sdk/aptos'; +import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +import { getSigner } from './helpers/index.js'; -Existing solutions for cross-chain transfers can be complex and inefficient, requiring multiple steps and transaction fees. However, the Token Bridge method from Wormhole simplifies the process by handling the underlying attestation, transaction validation, and message passing across blockchains. +(async function () { + const wh = await wormhole('Testnet', [ + evm, + solana, + aptos, + algorand, + cosmwasm, + sui, + ]); -At the end of this guide, you’ll have a fully functional setup for transferring assets across chains using Wormhole’s Token Bridge method. + const ctx = wh.getChain('Solana'); -## Prerequisites + const rcv = wh.getChain('Algorand'); -Before you begin, ensure you have the following: + const sender = await getSigner(ctx); + const receiver = await getSigner(rcv); - - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine - - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally - - Native tokens (testnet or mainnet) in Solana and Sui wallets - - A wallet with a private key, funded with native tokens (testnet or mainnet) for gas fees + // Get a Token Bridge contract client on the source + const sndTb = await ctx.getTokenBridge(); -## Supported Chains + // Send the native token of the source chain + const tokenId = Wormhole.tokenId(ctx.chain, 'native'); -The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains on the [Contract Addresses](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} page, which includes every network where Wormhole smart contracts are deployed, across both mainnet and testnet. + // Bigint amount using `amount` module + const amt = amount.units(amount.parse('0.1', ctx.config.nativeTokenDecimals)); -## Project Setup + // Create a transaction stream for transfers + const transfer = sndTb.transfer( + sender.address.address, + receiver.address, + tokenId.address, + amt + ); -In this section, we’ll guide you through initializing the project, installing dependencies, and preparing your environment for cross-chain transfers. + // Sign and send the transaction + const txids = await signSendWait(ctx, transfer, sender.signer); + console.log('Sent: ', txids); -1. **Initialize the project** - start by creating a new directory for your project and initializing it with `npm`, which will create the `package.json` file for your project + // Get the Wormhole message ID from the transaction + const [whm] = await ctx.parseTransaction(txids[txids.length - 1]!.txid); + console.log('Wormhole Messages: ', whm); - ```bash - mkdir native-transfers - cd native-transfers - npm init -y - ``` + const vaa = await wh.getVaa( + // Wormhole Message ID + whm!, + // Protocol:Payload name to use for decoding the VAA payload + 'TokenBridge:Transfer', + // Timeout in milliseconds, depending on the chain and network, the VAA may take some time to be available + 60_000 + ); -2. **Create a `.gitignore` file** - ensure your private key isn't accidentally exposed or committed to version control + // Now get the token bridge on the redeem side + const rcvTb = await rcv.getTokenBridge(); - ```bash - echo ".env" >> .gitignore - ``` + // Create a transaction stream for redeeming + const redeem = rcvTb.redeem(receiver.address.address, vaa!); -3. **Install dependencies** - install the required dependencies, including the Wormhole SDK and helper libraries + // Sign and send the transaction + const rcvTxids = await signSendWait(rcv, redeem, receiver.signer); + console.log('Sent: ', rcvTxids); - ```bash - npm install @wormhole-foundation/sdk dotenv tsx - ``` + // Now check if the transfer is completed according to + // the destination token bridge + const finished = await rcvTb.isTransferCompleted(vaa!); + console.log('Transfer completed: ', finished); +})(); +``` -4. **Set up environment variables** - to securely store your private key, create a `.env` file in the root of your project +Then, import each of the ecosystem [platforms](/docs/tools/typescript-sdk/sdk-reference/#platforms) that you wish to support: - ```bash - touch .env - ``` +```ts +import aptos from '@wormhole-foundation/sdk/aptos'; +import cosmwasm from '@wormhole-foundation/sdk/cosmwasm'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import sui from '@wormhole-foundation/sdk/sui'; +``` - Inside the `.env` file, add your private keys. +To make the [platform](/docs/tools/typescript-sdk/sdk-reference/#platforms) modules available for use, pass them to the Wormhole constructor and specify the network (`Mainnet`, `Testnet`, or `Devnet`) you want to interact with: - ```env - ETH_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" - SOL_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" - SUI_PRIVATE_KEY="INSERT_SUI_MNEMONIC" - ``` +```ts +evm, + solana, + aptos, + algorand, + cosmwasm, + sui, + ]); +``` - !!! note - Ensure your private key contains native tokens for gas on both the source and destination chains. For Sui, you must provide a mnemonic instead of a private key. +With a configured `Wormhole` object, you can begin to interact with these chains. -5. **Create a `helpers.ts` file** - to simplify the interaction between chains, create a file to store utility functions for fetching your private key, set up signers for different chains, and manage transaction relays +## Example Usage - 1. Create the helpers file +Follow these steps to confirm that the SDK is initialized correctly and can fetch basic chain information for your target chains. - ```bash - mkdir -p src/helpers - touch src/helpers/helpers.ts - ``` +### Prerequisites - 2. Open the `helpers.ts` file and add the following code +Before you begin, make sure you have the following: - ```typescript - import { - ChainAddress, - ChainContext, - Network, - Signer, - Wormhole, - Chain, - TokenId, - isTokenId, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import aptos from '@wormhole-foundation/sdk/aptos'; -import { config } from 'dotenv'; -config(); + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed + - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed -export interface SignerStuff { - chain: ChainContext; - signer: Signer; - address: ChainAddress; -} +??? example "Project setup instructions" + + Use the following commands to create a TypeScript project: -// Function to fetch environment variables (like your private key) -function getEnv(key: string): string { - const val = process.env[key]; - if (!val) throw new Error(`Missing environment variable: ${key}`); - return val; -} + 1. Create a directory and initialize a Node.js project: -// Signer setup function for different blockchain platforms -export async function getSigner( - chain: ChainContext, - gasLimit?: bigint -): Promise<{ - chain: ChainContext; - signer: Signer; - address: ChainAddress; -}> { - let signer: Signer; - const platform = chain.platform.utils()._platform; + ```bash + mkdir wh-ts-demo + cd wh-ts-demo + npm init -y + ``` - switch (platform) { - case 'Solana': - signer = await ( - await solana() - ).getSigner(await chain.getRpc(), getEnv('SOL_PRIVATE_KEY')); - break; - case 'Evm': - const evmSignerOptions = gasLimit ? { gasLimit } : {}; - signer = await ( - await evm() - ).getSigner( - await chain.getRpc(), - getEnv('ETH_PRIVATE_KEY'), - evmSignerOptions - ); - break; - case 'Sui': - signer = await ( - await sui() - ).getSigner(await chain.getRpc(), getEnv('SUI_MNEMONIC')); - break; - case 'Aptos': - signer = await ( - await aptos() - ).getSigner(await chain.getRpc(), getEnv('APTOS_PRIVATE_KEY')); - break; - default: - throw new Error('Unsupported platform: ' + platform); - } + 2. Install TypeScript, `tsx` (for running TypeScript files), Node.js type definitions, the base Wormhole SDK, and the platform-specific packages for the chains you want to interact with: - return { - chain, - signer: signer as Signer, - address: Wormhole.chainAddress(chain.chain, signer.address()), - }; -} + ```bash + npm install --save-dev tsx typescript @types/node @wormhole-foundation/sdk @wormhole-foundation/sdk-evm @wormhole-foundation/sdk-solana + ``` -export async function getTokenDecimals< - N extends 'Mainnet' | 'Testnet' | 'Devnet' ->( - wh: Wormhole, - token: TokenId, - sendChain: ChainContext -): Promise { - return isTokenId(token) - ? Number(await wh.getDecimals(token.chain, token.address)) - : sendChain.config.nativeTokenDecimals; -} - + 3. Create a `tsconfig.json` if you don't have one. You can generate a basic one using the following command: + + ```bash + npx tsc --init ``` - - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file - - **`getSigner`** - based on the chain you're working with (EVM, Solana, Sui, etc.), this function retrieves a signer for that specific platform. The signer is responsible for signing transactions and interacting with the blockchain. It securely uses the private key stored in your `.env` file - - **`getTokenDecimals`** - this function fetches the number of decimals for a token on a specific chain. It helps handle token amounts accurately during transfers + Make sure your `tsconfig.json` includes the following settings: -## Check and Create Wrapped Tokens + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` -Before tokens are transferred across chains, it should be checked whether a wrapped version exists on the destination chain. If not, an attestation must be generated to wrap it so it can be sent and received on that chain. + 4. Initialize the main `Wormhole` class to use the SDK. Create a new TypeScript file named `src/main.ts` in your project directory: -In this section, you'll create a script that automates this process by checking whether Arbitrum Sepolia has a wrapped version on Base Sepolia and registering it if needed. + ```bash + mkdir src + touch src/main.ts + ``` -### Configure the Wrapped Token Script + 5. Add the following code to initialize the SDK and use the `Wormhole` instance to return the chain ID and RPC for the chains this instance supports: -1. **Create the `create-wrapped.ts` file** - set up the script file that will handle checking and wrapping tokens in the `src` directory + ```ts title="src/main.ts" + import { wormhole } from '@wormhole-foundation/sdk'; +// Import specific platform modules for the chains you intend to use +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; - ```bash - mkdir -p src/scripts - touch src/scripts/create-wrapped.ts - ``` +async function main() { + console.log('Initializing Wormhole SDK...'); -2. **Open `create-wrapped.ts` and import the required modules** - import the necessary SDK modules to interact with Wormhole, EVM, Solana, and Sui chains, as well as helper functions for signing and sending transactions + // Determine the network: "Mainnet", "Testnet", or "Devnet" + const network = 'Testnet'; - ```typescript - import evm from '@wormhole-foundation/sdk/evm'; + // Initialize the SDK with the chosen network and platform contexts + const wh = await wormhole(network, [evm, solana]); + + console.log('Wormhole SDK Initialized!'); +} + +main().catch((e) => { + console.error('Error initializing Wormhole SDK', e); + process.exit(1); +}); + ``` + +### Fetch Chain Information + +1. Update the `main` function as follows to retrieve the chain ID and RPC for the chains your project supports: + + ```ts title="src/main.ts" + import { wormhole } from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { inspect } from 'util'; -import { getSigner } from '../helpers/helpers'; - ``` -3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support +async function main() { + console.log('Initializing Wormhole SDK...'); - ```typescript - const wh = await wormhole('Testnet', [evm, solana, sui]); - ``` + const network = 'Testnet'; + const wh = await wormhole(network, [evm, solana]); - !!! note - You can replace `'Testnet'` with `'Mainnet'` if you want to perform transfers on Mainnet. + console.log('Wormhole SDK Initialized!'); -4. **Configure transfer parameters** - specify Arbitrum Sepolia as the source chain and Base Sepolia as the destination, retrieve the token ID from the source chain for transfer, and set the gas limit (optional) + // Example: Get a chain ID and RPC for Solana + const solanaDevnetChain = wh.getChain('Solana'); + console.log( + `Chain ID for Solana Testnet: ${solanaDevnetChain.config.chainId}` + ); + console.log(`RPC for Solana Testnet: ${solanaDevnetChain.config.rpc}`); - ```typescript - const destChain = wh.getChain('BaseSepolia'); - const token = await srcChain.getNativeWrappedTokenId(); - const gasLimit = BigInt(2_500_000); + // Example: Get a chain ID for Sepolia (EVM Testnet) + const sepoliaChain = wh.getChain('Sepolia'); + console.log(`Chain ID for Sepolia: ${sepoliaChain.config.chainId}`); + console.log(`RPC for Sepolia: ${sepoliaChain.config.rpc}`); +} + +main().catch((e) => { + console.error( + 'Error initializing Wormhole SDK or fetching chain information:', + e + ); + process.exit(1); +}); ``` -5. **Set up the destination chain signer** - the signer authorizes transactions, such as submitting the attestation +2. Run the script with the following command, replacing `INSERT_FILE_NAME` with your file name: - ```typescript - + ```bash + npx tsx INSERT_FILE_NAME ``` -6. **Check if the token is wrapped on the destination chain** - verify if the token already exists as a wrapped asset before creating an attestation + You will see terminal output similar to the following: - ```typescript - try { - const wrapped = await tbDest.getWrappedAsset(token); - console.log( - `Token already wrapped on ${destChain.chain}. Skipping attestation.` - ); - return { chain: destChain.chain, address: wrapped }; - } catch (e) { - console.log( - `No wrapped token found on ${destChain.chain}. Proceeding with attestation.` - ); - } - ``` +
+npx tsx src/main.ts +Initializing Wormhole SDK... +Wormhole SDK Initialized! +Chain ID for Solana Testnet: 1 +RPC for Solana Testnet: https://api.devnet.solana.com +Chain ID for Sepolia: 10002 +RPC for Sepolia: https://ethereum-sepolia.publicnode.com + +
+ +Congratulations! You’ve successfully installed the Wormhole TypeScript SDK and initialized a `Wormhole` instance. Consider the following options to build on what you've accomplished. - If the token is already wrapped, the script exits, and you may proceed to the [next section](/docs/tutorials/typescript-sdk/tokens-via-token-bridge/#token-transfers). Otherwise, an attestation must be generated. +## Next Steps -7. **Set up the source chain signer** - the signer creates and submits the attestation transaction +- [Get familiar with the SDK](/docs/tools/typescript-sdk/sdk-reference/) +- [Send a multichain message](/docs/products/messaging/get-started/) +- [Transfer assets via the Token Bridge](/docs/products/token-bridge/tutorials/transfer-workflow/) +- [Transfer USDC via the CCTP Bridge](/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/) +--- END CONTENT --- - ```typescript - - ``` +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/protocols-payloads/ +--- BEGIN CONTENT --- +--- +title: Building Protocols and Payloads +description: Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. +categories: Typescript-SDK +--- -8. **Create an attestation transaction** - generate and send an attestation for the token on the source chain to register it on the destination chain, then save the transaction ID to verify the attestation in the next step +# Building Protocols and Payloads - ```typescript - const attestTxns = tbOrig.createAttestation( - token.address, - Wormhole.parseAddress(origSigner.chain(), origSigner.address()) - ); +## Introduction - const txids = await signSendWait(srcChain, attestTxns, origSigner); - console.log('txids: ', inspect(txids, { depth: null })); - const txid = txids[0]!.txid; - console.log('Created attestation (save this): ', txid); - ``` +The [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} provides a flexible and powerful system for integrating cross-chain communication into your applications. A key feature of the SDK is its ability to define protocols—modular units representing distinct functionalities—and their associated payloads, which encapsulate the data required for specific operations within those protocols. -9. **Retrieve the signed VAA** - once the attestation transaction is confirmed, use `parseTransaction(txid)` to extract Wormhole messages, then retrieve the signed VAA from the messages. The timeout defines how long to wait for the VAA before failure +This guide will help you understand how to build protocols and payloads in the SDK, covering: - ```typescript - console.log('Parsed Messages:', msgs); + - The role of protocols and payloads in cross-chain communication + - The mechanics of registering protocols and payloads using the SDK + - Best practices for creating strongly typed layouts to ensure compatibility and reliability + - Real-world examples using the `TokenBridge` as a reference implementation - const timeout = 25 * 60 * 1000; - const vaa = await wh.getVaa(msgs[0]!, 'TokenBridge:AttestMeta', timeout); - if (!vaa) { - throw new Error( - 'VAA not found after retries exhausted. Try extending the timeout.' - ); - } - ``` +By the end of this guide, you’ll have a solid understanding of how to define, register, and use protocols and payloads in your projects. -10. **Submit the attestation on the destination chain** - submit the signed VAA using `submitAttestation(vaa, recipient)` to create the wrapped token on the destination chain, then send the transaction and await confirmation +## What is a Protocol? - ```typescript - vaa, - Wormhole.parseAddress(destSigner.chain(), destSigner.address()) - ); +In the Wormhole SDK, a protocol represents a significant feature or functionality that operates across multiple blockchains. Protocols provide the framework for handling specific types of messages, transactions, or operations consistently and standardized. - const tsx = await signSendWait(destChain, subAttestation, destSigner); - ``` +Examples of Protocols: -11. **Wait for the wrapped asset to be available** - poll until the wrapped token is available on the destination chain + - **`TokenBridge`** - enables cross-chain token transfers, including operations like transferring tokens and relaying payloads + - **`NTT (Native Token Transfers)`** - manages native token movements across chains - ```typescript - do { - try { - const wrapped = await tbDest.getWrappedAsset(token); - return { chain: destChain.chain, address: wrapped }; - } catch (e) { - console.error('Wrapped asset not found yet. Retrying...'); - } - console.log('Waiting before checking again...'); - await new Promise((r) => setTimeout(r, 2000)); - } while (true); - } +Protocols are defined by: - console.log('Wrapped Asset: ', await waitForIt()); -})().catch((e) => console.error(e)); - ``` + - **A `name`** - a string identifier (e.g., `TokenBridge`, `Ntt`) + - **A set of `payloads`** - these represent the specific actions or messages supported by the protocol, such as `Transfer` or `TransferWithPayload` - If the token is not found, it logs a message and retries after a short delay. Once the wrapped asset is detected, its address is returned. +Each protocol is registered in the Wormhole SDK, allowing developers to leverage its predefined features or extend it with custom payloads. -??? code "Complete script" - ```typescript - import { Wormhole, signSendWait, wormhole } from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { inspect } from 'util'; -import { getSigner } from '../helpers/helpers'; +## What is a Payload? -(async function () { - const wh = await wormhole('Testnet', [evm, solana, sui]); +A payload is a structured piece of data that encapsulates the details of a specific operation within a protocol. It defines the format, fields, and types of data used in a message or transaction. Payloads ensure consistency and type safety when handling complex cross-chain operations. - // Define the source and destination chains - const srcChain = wh.getChain('ArbitrumSepolia'); - const destChain = wh.getChain('BaseSepolia'); - const token = await srcChain.getNativeWrappedTokenId(); - const gasLimit = BigInt(2_500_000); +Each payload is defined as: - // Destination chain signer setup - const { signer: destSigner } = await getSigner(destChain, gasLimit); - const tbDest = await destChain.getTokenBridge(); + - **A `layout`** - describes the binary format of the payload fields + - **A `literal`** - combines the protocol name and payload name into a unique identifier (e.g., `TokenBridge:Transfer`) - try { - const wrapped = await tbDest.getWrappedAsset(token); - console.log( - `Token already wrapped on ${destChain.chain}. Skipping attestation.` - ); - return { chain: destChain.chain, address: wrapped }; - } catch (e) { - console.log( - `No wrapped token found on ${destChain.chain}. Proceeding with attestation.` - ); - } +By registering payloads, developers can enforce type safety and enable serialization and deserialization for specific protocol operations. - // Source chain signer setup - const { signer: origSigner } = await getSigner(srcChain); +## Register Protocols and Payloads - // Create an attestation transaction on the source chain - const tbOrig = await srcChain.getTokenBridge(); - const attestTxns = tbOrig.createAttestation( - token.address, - Wormhole.parseAddress(origSigner.chain(), origSigner.address()) - ); +Protocols and payloads work together to enable cross-chain communication with precise type safety. For instance, in the `TokenBridge` protocol: - const txids = await signSendWait(srcChain, attestTxns, origSigner); - console.log('txids: ', inspect(txids, { depth: null })); - const txid = txids[0]!.txid; - console.log('Created attestation (save this): ', txid); + - The protocol is registered under the `TokenBridge` namespace + - Payloads like `Transfer` or `AttestMeta` are linked to the protocol to handle specific operations - // Retrieve the Wormhole message ID from the attestation transaction - const msgs = await srcChain.parseTransaction(txid); - console.log('Parsed Messages:', msgs); +Understanding the connection between these components is important for customizing or extending the SDK to suit your needs. - const timeout = 25 * 60 * 1000; - const vaa = await wh.getVaa(msgs[0]!, 'TokenBridge:AttestMeta', timeout); - if (!vaa) { - throw new Error( - 'VAA not found after retries exhausted. Try extending the timeout.' - ); - } +### Register Protocols - console.log('Token Address: ', vaa.payload.token.address); +Registering a protocol establishes its connection to Wormhole's infrastructure, ensuring it interacts seamlessly with payloads and platforms while maintaining type safety and consistency. - // Submit the attestation on the destination chain - console.log('Attesting asset on destination chain...'); +#### How Protocol Registration Works - const subAttestation = tbDest.submitAttestation( - vaa, - Wormhole.parseAddress(destSigner.chain(), destSigner.address()) - ); +Protocol registration involves two key tasks: - const tsx = await signSendWait(destChain, subAttestation, destSigner); - console.log('Transaction hash: ', tsx); + - **Mapping protocols to interfaces** - connect the protocol to its corresponding interface, defining its expected behavior across networks (`N`) and chains (`C`). This ensures type safety, similar to strong typing, by preventing runtime errors if protocol definitions are incorrect + - **Linking protocols to platforms** - specify platform-specific implementations if needed, or use default mappings for platform-agnostic protocols - // Poll for the wrapped asset until it's available - async function waitForIt() { - do { - try { - const wrapped = await tbDest.getWrappedAsset(token); - return { chain: destChain.chain, address: wrapped }; - } catch (e) { - console.error('Wrapped asset not found yet. Retrying...'); - } - console.log('Waiting before checking again...'); - await new Promise((r) => setTimeout(r, 2000)); - } while (true); +For example, here's the `TokenBridge` protocol registration: + +```typescript +declare module '../../registry.js' { + export namespace WormholeRegistry { + interface ProtocolToInterfaceMapping { + TokenBridge: TokenBridge; + } + interface ProtocolToPlatformMapping { + TokenBridge: EmptyPlatformMap<'TokenBridge'>; + } } +} + +``` - console.log('Wrapped Asset: ', await waitForIt()); -})().catch((e) => console.error(e)); - ``` +This code snippet: -### Run the Wrapped Token Creation + - Maps the `TokenBridge` protocol to its interface to define how it operates + - Links the protocol to a default platform mapping via `EmptyPlatformMap` -Once the script is ready, execute it with: +You can view the full implementation in the [`TokenBridge` protocol file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L14-L70){target=\_blank}. -```bash -npx tsx src/scripts/create-wrapped.ts -``` +#### Platform-Specific Protocols -If the token is already wrapped, the script exits. Otherwise, it generates an attestation and submits it. Once complete, you’re ready to transfer tokens across chains. +Some protocols require platform-specific behavior. For instance, the EVM-compatible Wormhole Registry maps native addresses for Ethereum-based chains: -## Token Transfers +```typescript +declare module '@wormhole-foundation/sdk-connect' { + export namespace WormholeRegistry { + interface PlatformToNativeAddressMapping { + Evm: EvmAddress; + } + } +} -In this section, you'll create a script to transfer native tokens across chains using Wormhole's Token Bridge method. The script will handle the transfer of Sui native tokens to Solana, demonstrating the seamless cross-chain transfer capabilities of the Wormhole SDK. Since both chains are non-EVM compatible, you'll need to manually handle the attestation and finalization steps. +registerNative(_platform, EvmAddress); +``` -### Configure Transfer Details +This ensures that `EvmAddress` is registered as the native address type for EVM-compatible platforms. See the [EVM platform address file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/platforms/evm/src/address.ts#L98-L106){target=\_blank} for details. -Before initiating a cross-chain transfer, you must set up the chain context and signers for both the source and destination chains. +### Register Payloads -1. Create the `native-transfer.ts` file in the `src` directory to hold your script for transferring native tokens across chains +[Payload registration](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts){target=\_blank} enables developers to define, serialize, and handle custom message types within their protocols. It establishes the connection between a protocol and its payloads, ensuring seamless integration, type enforcement, and runtime efficiency. - ```bash - touch src/scripts/native-transfer.ts - ``` +This process ties a protocol to its payloads using a combination of: -2. Open the `native-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files + - **Payload literals** - unique identifiers in the format `:`. These literals map each payload to a layout + - **Payload layouts** - structures that define the binary representation of payload data + - **The payload factory** - a centralized runtime registry that maps payload literals to layouts for dynamic resolution and serialization - ```typescript - Chain, - Network, - Wormhole, - amount, - wormhole, - TokenId, - TokenTransfer, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; - ``` +These components work together to streamline the definition and management of protocol payloads. -3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support +#### How Payload Registration Works - ```typescript - const wh = await wormhole('Testnet', [evm, solana, sui]); - ``` +Payload registration involves: -4. **Set up source and destination chains** - specify the source chain (Sui) and the destination chain (Solana) using the `getChain` method. This allows us to define where to send the native tokens and where to receive them +1. **Define payload layouts** - create layouts to structure your payloads. For instance, a protocol might use a `TransferWithPayload` layout: ```typescript - const rcvChain = wh.getChain('Solana'); + export const transferWithPayloadLayout = < + const P extends CustomizableBytes = undefined +>( + customPayload?: P +) => + [ + payloadIdItem(3), + ...transferCommonLayout, + { name: 'from', ...universalAddressItem }, + customizableBytes({ name: 'payload' }, customPayload), + ] as const; ``` -5. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains +2. **Register payloads** - use `registerPayloadTypes` to map payload literals to their layouts: ```typescript - const destination = await getSigner(rcvChain); + registerPayloadTypes('ProtocolName', protocolNamedPayloads); ``` -6. **Define the token to transfer** - specify the native token on the source chain (Sui in this example) by creating a `TokenId` object +3. **Access registered payloads** - use the [`getPayloadLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/9105de290c91babbf8ad031bd89cc75ee38739c8/core/definitions/src/vaa/functions.ts#L19-L23){target=\_blank} function to fetch the layout for a specific payload literal. This method ensures that the correct layout is retrieved dynamically and safely: ```typescript - + const layout = getPayloadLayout('ProtocolName:PayloadName'); ``` -7. **Define the transfer amount** - the amount of native tokens to transfer is specified. In this case, we're transferring 1 unit +These steps link payload literals and their layouts, enabling seamless runtime handling. - ```typescript - - ``` +#### The Payload Factory -8. **Set transfer mode** - specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself +At the core of the payload registration process is the `payloadFactory`, a registry that manages the mapping between payload literals and layouts: - ```typescript - - ``` +```typescript +export const payloadFactory = new Map(); - !!! note - Automatic transfers are only supported for EVM chains. For non-EVM chains like Solana and Sui, you must manually handle the attestation and finalization steps. - -9. **Define decimals** - fetch the number of decimals for the token on the source chain (Sui) using the `getTokenDecimals` function +export function registerPayloadType( + protocol: ProtocolName, + name: string, + layout: Layout +) { + const payloadLiteral = composeLiteral(protocol, name); + if (payloadFactory.has(payloadLiteral)) { + throw new Error(`Payload type ${payloadLiteral} already registered`); + } + payloadFactory.set(payloadLiteral, layout); +} + +``` - ```typescript - - ``` + - The `payloadFactory` ensures each payload literal maps to its layout uniquely + - The [`registerPayloadType`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts#L46-L52){target=\_blank} function adds individual payloads, while [`registerPayloadTypes`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/vaa/registration.ts#L62-L64){target=\_blank} supports bulk registration -10. **Perform the token transfer and exit the process** - initiate the transfer by calling the `tokenTransfer` function, which we’ll define in the next step. This function takes an object containing all required details for executing the transfer, including the `source` and `destination` chains, `token`, `mode`, and transfer `amount` +This implementation ensures dynamic, efficient handling of payloads at runtime. - ```typescript - token, - amount: amount.units(amount.parse(amt, decimals)), - source, - destination, - automatic, - }); - ``` +## Integrate Protocols with Payloads - Finally, we use `process.exit(0);` to close the script once the transfer completes +Integrating payloads with protocols enables dynamic identification through payload literals, while serialization and deserialization ensure their binary representation is compatible across chains. For more details on these processes, refer to the [Layouts page](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank}. - ```typescript - })(); - ``` +### Payload Discriminators -### Token Transfer Logic +Payload discriminators are mechanisms in the Wormhole SDK that dynamically identify and map incoming payloads to their respective layouts at runtime. They are relevant for protocols like `TokenBridge`, enabling efficient handling of diverse payload types while ensuring type safety and consistent integration. -This section defines the `tokenTransfer` function, which manages the core steps for cross-chain transfer execution. This function will handle initiating the transfer on the source chain, retrieving the attestation, and completing the transfer on the destination chain. +#### How Discriminators Work -#### Defining the Token Transfer Function +Discriminators evaluate serialized binary data and determine the corresponding payload layout by inspecting fixed fields or patterns within the data. Each payload layout is associated with a payload literal (e.g., `TokenBridge:Transfer` or `TokenBridge:TransferWithPayload`). -The `tokenTransfer` function initiates and manages the transfer process, handling all necessary steps to move tokens across chains with the Wormhole SDK. This function uses types from the SDK and our `helpers.ts` file to ensure chain compatibility. +This system ensures: + + - **Dynamic runtime identification** - payloads are parsed based on their content, even if a single protocol handles multiple payload types + - **Strict type enforcement** - discriminators leverage layout mappings to prevent invalid payloads from being processed + +Below is an example of how the Wormhole SDK builds a discriminator to distinguish between payload layouts: ```typescript -wh: Wormhole, - route: { - token: TokenId; - amount: bigint; - source: SignerStuff; - destination: SignerStuff; - automatic: boolean; - payload?: Uint8Array; +export function layoutDiscriminator( + layouts: readonly Layout[], + allowAmbiguous?: B +): Discriminator { + // Internal logic to determine distinguishable layouts + const [distinguishable, discriminator] = internalBuildDiscriminator(layouts); + if (!distinguishable && !allowAmbiguous) { + throw new Error('Cannot uniquely distinguish the given layouts'); } -) { - // Token Transfer Logic -import { - Chain, - Network, - Wormhole, - amount, - wormhole, - TokenId, - TokenTransfer, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; -(async function () { - const wh = await wormhole('Testnet', [evm, solana, sui]); + return ( + !allowAmbiguous + ? (encoded: BytesType) => { + const layout = discriminator(encoded); + return layout.length === 0 ? null : layout[0]; + } + : discriminator + ) as Discriminator; +} + +``` - // Set up source and destination chains - const sendChain = wh.getChain('Sui'); - const rcvChain = wh.getChain('Solana'); + - [`layoutDiscriminator`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/9105de290c91babbf8ad031bd89cc75ee38739c8/core/base/src/utils/layout.ts#L16){target=\_blank} takes a list of layouts and generates a function that can identify the appropriate layout for a given serialized payload + - The `allowAmbiguous` parameter determines whether layouts with overlapping characteristics are permitted - // Get signer from local key but anything that implements - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); +### Real-World Example: Token Bridge Protocol - // Shortcut to allow transferring native gas token - const token = Wormhole.tokenId(sendChain.chain, 'native'); +Integrating protocols with their respective payloads exemplifies how the Wormhole SDK leverages layouts and type-safe registration mechanisms to ensure efficient cross-chain communication. This section focuses on how protocols like `TokenBridge` use payloads to facilitate specific operations. - // Define the amount of tokens to transfer - const amt = '1'; +#### Token Bridge Protocol and Payloads + +The `TokenBridge` protocol enables cross-chain token transfers through its payloads. Key payloads include: + + - **`Transfer`** - handles basic token transfer operations + - **`TransferWithPayload`** - extends the `Transfer` payload to include custom data, enhancing functionality + +Payloads are registered to the `TokenBridge` protocol via the `PayloadLiteralToLayoutMapping` interface, which links payload literals (e.g., `TokenBridge:Transfer`) to their layouts. + +Additionally, the protocol uses reusable layouts like [`transferCommonLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/76b20317b0f68e823d4e6c4a2e41bb2a7705c64f/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts#L29C7-L47){target=\_blank} and extends them in more specialized layouts such as [`transferWithPayloadLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/76b20317b0f68e823d4e6c4a2e41bb2a7705c64f/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts#L49-L57){target=\_blank}: + +```typescript +export const transferWithPayloadLayout = < + const P extends CustomizableBytes = undefined +>( + customPayload?: P +) => + [ + payloadIdItem(3), + ...transferCommonLayout, + { name: 'from', ...universalAddressItem }, + customizableBytes({ name: 'payload' }, customPayload), + ] as const; +``` + +This layout includes: + + - A `payloadIdItem` to identify the payload type + - Common fields for token and recipient details + - A customizable `payload` field for additional data + +#### Use the Discriminator + +To manage multiple payloads, the `TokenBridge` protocol utilizes a discriminator to distinguish between payload types dynamically. For example: + +```typescript +const tokenBridgePayloads = ['Transfer', 'TransferWithPayload'] as const; + +export const getTransferDiscriminator = lazyInstantiate(() => + payloadDiscriminator([_protocol, tokenBridgePayloads]) +); +``` + + - The [`getTransferDiscriminator`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dbbbc7c365db602dd3b534f6d615ac80c3d2aaf1/core/definitions/src/protocols/tokenBridge/tokenBridge.ts#L67-L70){target=\_blank} function dynamically evaluates payloads using predefined layouts + - This ensures that each payload type is processed according to its unique structure and type-safe layout + +#### Register Payloads to Protocols - // Set automatic transfer to false for manual transfer - const automatic = false; +Here’s how the `TokenBridge` protocol connects its payloads to the Wormhole SDK: - // Used to normalize the amount to account for the tokens decimals - const decimals = await getTokenDecimals(wh, token, sendChain); +```typescript +declare module '../../registry.js' { + export namespace WormholeRegistry { + interface PayloadLiteralToLayoutMapping + extends RegisterPayloadTypes< + 'TokenBridge', + typeof tokenBridgeNamedPayloads + > {} + } +} - // Perform the token transfer if no recovery transaction ID is provided - const xfer = await tokenTransfer(wh, { - token, - amount: amount.units(amount.parse(amt, decimals)), - source, - destination, - automatic, - }); +registerPayloadTypes('TokenBridge', tokenBridgeNamedPayloads); +``` - process.exit(0); -})(); +This registration links the `TokenBridge` payload literals to their respective layouts, enabling serialization and deserialization at runtime. -async function tokenTransfer( - wh: Wormhole, - route: { - token: TokenId; - amount: bigint; - source: SignerStuff; - destination: SignerStuff; - automatic: boolean; - payload?: Uint8Array; - } -) { - // Token Transfer Logic - // Create a TokenTransfer object to track the state of the transfer over time - const xfer = await wh.tokenTransfer( - route.token, - route.amount, - route.source.address, - route.destination.address, - route.automatic ?? false, - route.payload - ); +You can explore the complete `TokenBridge` protocol and payload definitions in the [`TokenBridge` layout file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts){target=\_blank}. - const quote = await TokenTransfer.quoteTransfer( - wh, - route.source.chain, - route.destination.chain, - xfer.transfer - ); +#### Token Bridge Payloads - if (xfer.transfer.automatic && quote.destinationToken.amount < 0) - throw 'The amount requested is too low to cover the fee and any native gas requested.'; +The following payloads are registered for the `TokenBridge` protocol: - // Submit the transactions to the source chain, passing a signer to sign any txns - console.log('Starting transfer'); - const srcTxids = await xfer.initiateTransfer(route.source.signer); - console.log(`Source Trasaction ID: ${srcTxids[0]}`); - console.log(`Wormhole Trasaction ID: ${srcTxids[1] ?? srcTxids[0]}`); + - **`AttestMeta`** - used for token metadata attestation + - **`Transfer`** - facilitates token transfers + - **`TransferWithPayload`** - adds a custom payload to token transfers - // Wait for the VAA to be signed and ready (not required for auto transfer) - console.log('Getting Attestation'); - await xfer.fetchAttestation(60_000); +These payloads and their layouts are defined in the [`TokenBridge` layout file](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/protocols/tokenBridge/tokenBridgeLayout.ts){target=\_blank}. - // Redeem the VAA on the dest chain - console.log('Completing Transfer'); - const destTxids = await xfer.completeTransfer(route.destination.signer); - console.log(`Completed Transfer: `, destTxids); -} - -``` +### Other Protocols: Native Token Transfers (NTT) -#### Steps to Transfer Tokens +While this guide focuses on the `TokenBridge` protocol, other protocols, like NTT, follow a similar structure. -The `tokenTransfer` function consists of several key steps to facilitate the cross-chain transfer. Let’s break down each step: + - NTT manages the transfer of native tokens across chains + - Payloads such as `WormholeTransfer` and `WormholeTransferStandardRelayer` are registered to the protocol using the same patterns for payload literals and layouts + - The same mechanisms for type-safe registration and payload discriminators apply, ensuring reliability and extensibility -1. **Initialize the transfer object** - the `tokenTransfer` function begins by creating a `TokenTransfer` object, `xfer`, which tracks the state of the transfer process and provides access to relevant methods for each transfer step +For more details, you can explore the [NTT implementation in the SDK](https://github.com/wormhole-foundation/example-native-token-transfers/blob/00f83aa215338b1b8fd66f522bd0f45be3e98a5a/sdk/definitions/src/ntt.ts){target=\_blank}. +--- END CONTENT --- - ```typescript - route.token, - route.amount, - route.source.address, - route.destination.address, - route.automatic ?? false, - route.payload - ); - ``` +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/sdk-layout/ +--- BEGIN CONTENT --- +--- +title: Data Layouts +description: Learn how to efficiently define, serialize, and deserialize data structures using Wormhole SDK's layout system for cross-chain communication. +categories: Typescript-SDK +--- -2. **Estimate transfer fees and validate amount** - we obtain a fee quote for the transfer before proceeding. This step is significant in automatic mode (`automatic = true`), where the quote will include additional fees for relaying +# Data Layouts - ```typescript - wh, - route.source.chain, - route.destination.chain, - xfer.transfer - ); +## Introduction - if (xfer.transfer.automatic && quote.destinationToken.amount < 0) - throw 'The amount requested is too low to cover the fee and any native gas requested.'; - ``` +The [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} uses the [layout package](https://www.npmjs.com/package/binary-layout){target=\_blank} to define, serialize, and deserialize data structures efficiently. This modular system ensures consistent data formatting and cross-environment compatibility, benefiting projects that require robust handling of structured data. -3. **Submit the transaction to the source chain** - initiate the transfer on the source chain by submitting the transaction using `route.source.signer`, starting the token transfer process +By understanding the layout mechanism, you’ll be able to: - ```typescript - console.log(`Source Trasaction ID: ${srcTxids[0]}`); - ``` + - Define data structures (numbers, arrays, and custom types) + - Efficiently serialize and deserialize data using the SDK’s utilities + - Handle protocol-specific layouts with ease - - **`srcTxids`** - the resulting transaction IDs are printed to the console. These IDs can be used to track the transfer’s progress on the source chain and [Wormhole network](https://wormholescan.io/#/?network=Testnet){target=\_blank} +This guide is beneficial for developers looking to integrate Wormhole into their applications or protocols, especially those dealing with complex payloads or cross-chain communication. - ???- note "How Cross-Chain Transfers Work in the Background" - When `xfer.initiateTransfer(route.source.signer)` is called, it initiates the transfer on the source chain. Here’s what happens in the background: +## Key Concepts - - **Token lock or burn** - tokens are either locked in a smart contract or burned on the source chain, representing the transfer amount - - **VAA creation** - Wormhole’s network of Guardians generates a Verifiable Action Approval (VAA)—a signed proof of the transaction, which ensures it’s recognized across chains - - **Tracking the transfer** - the returned transaction IDs allow you to track the transfer's progress both on the source chain and within Wormhole’s network - - **Redemption on destination** - once detected, the VAA is used to release or mint the corresponding token amount on the destination chain, completing the transfer +### Layout Items - This process ensures a secure and verifiable transfer across chains, from locking tokens on the source chain to redeeming them on the destination chain. +A layout defines how data structures should be serialized (converted into binary format) and deserialized (converted back into their original structure). This ensures consistent data formatting when transmitting information across different blockchain environments. -4. **Wait for the attestation** - retrieve the Wormhole attestation (VAA), which serves as cryptographic proof of the transfer. In manual mode, you must wait for the VAA before redeeming the transfer on the destination chain +Layouts are composed of [layout items](https://github.com/nonergodic/layout/blob/main/src/items.ts){target=\_blank}, which describe individual fields or sets of fields in your data. Each layout item specifies: - ```typescript - - ``` + - **`name`** - name of the field + - **`binary`** - type of data (e.g., `uint`, `bytes`) + - **`size`** - byte length for fixed-size fields within uint and bytes items only -5. **Complete the transfer on the destination chain** - redeem the VAA on the destination chain to finalize the transfer +Layout items can represent: - ```typescript - console.log(`Completed Transfer: `, destTxids); - ``` + - **Primitive types** - basic data types like unsigned integers (`uint`) or byte arrays (`bytes`) + - **Composite types** - more complex structures, such as arrays or nested objects -??? code "Complete script" - ```typescript - import { - Chain, - Network, - Wormhole, - amount, - wormhole, - TokenId, - TokenTransfer, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import sui from '@wormhole-foundation/sdk/sui'; -import { SignerStuff, getSigner, getTokenDecimals } from '../helpers/helpers'; +Below is an example of a layout that might be used to serialize a message across the Wormhole protocol: -(async function () { - const wh = await wormhole('Testnet', [evm, solana, sui]); +```typescript +const exampleLayout = [ + { name: 'sourceChain', binary: 'uint', size: 2 }, + { name: 'orderSender', binary: 'bytes', size: 32 }, + { name: 'redeemer', binary: 'bytes', size: 32 }, + { name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 }, +] as const; +``` - // Set up source and destination chains - const sendChain = wh.getChain('Sui'); - const rcvChain = wh.getChain('Solana'); +In this example: - // Get signer from local key but anything that implements - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); + - `sourceChain` is a 2-byte unsigned integer (`uint`) identifying the source blockchain + - `orderSender` is a fixed-length 32-byte array representing the sender's address + - `redeemer` is another 32-byte array used for the redeemer’s address + - `redeemerMessage` is a variable-length byte sequence, with its length specified by a 4-byte integer - // Shortcut to allow transferring native gas token - const token = Wormhole.tokenId(sendChain.chain, 'native'); +This layout definition ensures that all necessary data fields are consistently encoded and can be correctly interpreted when they are deserialized. - // Define the amount of tokens to transfer - const amt = '1'; +### Serialization and Deserialization - // Set automatic transfer to false for manual transfer - const automatic = false; +Serialization converts structured data into binary format; deserialization reverses this, reconstructing the original objects. - // Used to normalize the amount to account for the tokens decimals - const decimals = await getTokenDecimals(wh, token, sendChain); +You can serialize data using the `serializeLayout` function: - // Perform the token transfer if no recovery transaction ID is provided - const xfer = await tokenTransfer(wh, { - token, - amount: amount.units(amount.parse(amt, decimals)), - source, - destination, - automatic, - }); +```typescript +const serialized = serializeLayout(fillLayout, exampleFill); +``` - process.exit(0); -})(); +To deserialize the binary data back into a structured object, use the `deserializeLayout` function: -async function tokenTransfer( - wh: Wormhole, - route: { - token: TokenId; - amount: bigint; - source: SignerStuff; - destination: SignerStuff; - automatic: boolean; - payload?: Uint8Array; - } -) { - // Token Transfer Logic - // Create a TokenTransfer object to track the state of the transfer over time - const xfer = await wh.tokenTransfer( - route.token, - route.amount, - route.source.address, - route.destination.address, - route.automatic ?? false, - route.payload - ); +```typescript +const deserialized = deserializeLayout(fillLayout, serialized); +``` - const quote = await TokenTransfer.quoteTransfer( - wh, - route.source.chain, - route.destination.chain, - xfer.transfer - ); +### Custom Conversions - if (xfer.transfer.automatic && quote.destinationToken.amount < 0) - throw 'The amount requested is too low to cover the fee and any native gas requested.'; +Layouts also allow for custom conversions, which help map complex or custom types (like chain IDs or universal addresses) into a more usable format. This is useful when serializing or deserializing data that doesn’t fit neatly into simple types like integers or byte arrays. - // Submit the transactions to the source chain, passing a signer to sign any txns - console.log('Starting transfer'); - const srcTxids = await xfer.initiateTransfer(route.source.signer); - console.log(`Source Trasaction ID: ${srcTxids[0]}`); - console.log(`Wormhole Trasaction ID: ${srcTxids[1] ?? srcTxids[0]}`); +For example, consider a custom conversion for a chain ID: - // Wait for the VAA to be signed and ready (not required for auto transfer) - console.log('Getting Attestation'); - await xfer.fetchAttestation(60_000); +```typescript +const chainCustomConversion = { + to: (chainId: number) => toChain(chainId), + from: (chain: Chain) => chainToChainId(chain), +} satisfies CustomConversion; + +``` - // Redeem the VAA on the dest chain - console.log('Completing Transfer'); - const destTxids = await xfer.completeTransfer(route.destination.signer); - console.log(`Completed Transfer: `, destTxids); -} - - ``` +This setup allows Wormhole to convert between human-readable formats and binary-encoded data used in payloads. -### Run the Native Token Transfer +### Error Handling -Now that you’ve set up the project and defined the transfer logic, you can execute the script to transfer native tokens from the Sui chain to Solana. You can use `tsx` to run the TypeScript file directly: +The layout system performs error checks during serialization and deserialization. An error is thrown if data is incorrectly sized or in the wrong format. Refer to the below example: -```bash -npx tsx src/scripts/native-transfer.ts +```typescript +try { + deserializeLayout(fillLayout, corruptedData); +} catch (error) { + console.error('Error during deserialization:', error.message); +} ``` -This initiates the native token transfer from the source chain (Sui) and completes it on the destination chain (Solana). +## Application of Layouts -You can monitor the status of the transaction on the [Wormhole explorer](https://wormholescan.io/#/?network=Testnet){target=\_blank}. +This section will focus on applying the concepts explained earlier through examples. These will help developers better understand how to define layouts, serialize and deserialize data, and use custom conversions where needed. -## Resources +### Defining Layouts -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in [Wormhole's demo GitHub repository](https://github.com/wormhole-foundation/demo-basic-ts-sdk/){target=\_blank}. The repository includes all the example scripts and configurations needed to perform native token cross-chain transfers, including manual, automatic, and partial transfers using the Wormhole SDK. +To get started with layouts in Wormhole, you need to define your structure. A layout is simply a list of fields (layout items) describing how each data piece will be serialized. -## Conclusion +Consider the following layout for a payload: -You've successfully built a cross-chain token transfer application using Wormhole's TypeScript SDK and the Token Bridge method. This guide took you through the setup, configuration, and transfer logic required to move native tokens across non-EVM chains like Sui and Solana. +```typescript +const exampleLayout = [ + { name: 'sourceChain', binary: 'uint', size: 2 }, + { name: 'orderSender', binary: 'bytes', size: 32 }, + { name: 'redeemer', binary: 'bytes', size: 32 }, + { name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 }, +] as const; +``` -The same transfer logic will apply if you’d like to extend this application to different chain combinations, including EVM-compatible chains. ---- END CONTENT --- +In this example: -Doc-Content: https://wormhole.com/docs/tutorials/typescript-sdk/usdc-via-cctp/ ---- BEGIN CONTENT --- ---- -title: Transfer USDC via CCTP and Wormhole SDK -description: Learn how to perform USDC cross-chain transfers using Wormhole SDK and Circle's CCTP. Supports manual, automatic, and partial transfer recovery. ---- + - `sourceChain` is an unsigned integer (uint) of 2 bytes + - `orderSender` is a 32-byte fixed-length byte array + - `redeemer` is another 32-byte byte array + - `redeemerMessage` is a length-prefixed byte array, with the length specified by a 4-byte integer -# Transfer USDC via CCTP and Wormhole SDK +### Serialize Data -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-cctp-transfer){target=\_blank} +Once a layout is defined, the next step is to serialize data according to that structure. You can accomplish this using the `serializeLayout` function from the Wormhole SDK. -## Introduction +```typescript +const examplePayload = { + sourceChain: 6, + orderSender: new Uint8Array(32), + redeemer: new Uint8Array(32), + redeemerMessage: new Uint8Array([0x01, 0x02, 0x03]), +}; -In this guide, we will show you how to bridge native USDC across different blockchain networks using [Circle's Cross-Chain Transfer Protocol](/docs/learn/transfers/cctp/){target=\_blank} (CCTP) and [Wormhole’s TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main){target=\_blank}. +const serializedData = serializeLayout(exampleLayout, examplePayload); +``` -Traditionally, cross-chain transfers using CCTP involve multiple manual steps, such as initiating the transfer on the source chain, relaying messages between chains, and covering gas fees on both the source and destination chains. Without the TypeScript SDK, developers must handle these operations independently, adding complexity and increasing the chance for errors, mainly when dealing with gas payments on the destination chain and native gas token management. +This takes the data structure (`examplePayload`) and serializes it according to the rules defined in the layout (`exampleLayout`). The result is a `Uint8Array` representing the serialized binary data. -Wormhole’s TypeScript SDK simplifies this process by offering automated transfer relaying and handling gas payments on the destination chain. It also offers an option to include native gas tokens for seamless execution. This reduces developer overhead, makes transfers faster and more reliable, and enhances the user experience. +### Deserialize Data -In this guide, we’ll first explore the theory behind CCTP and then provide a step-by-step tutorial for integrating Wormhole’s TypeScript SDK into your application to streamline USDC transfers across multiple chains. +Deserialization is the reverse of serialization. Given a serialized `Uint8Array`, we can convert it back into its original structure using the `deserializeLayout` function. -## Core Concepts +```typescript +const deserializedPayload = deserializeLayout(exampleLayout, serializedData); +``` -When bridging assets across chains, there are two primary approaches to handling the transfer process: manual and automated. Below, you may find the differences between these approaches and how they impact the user experience: +This will output the structured object, making it easy to work with data transmitted or received from another chain. - - **Manual transfers** - manual transfers involve three key steps: initiating the transfer on the source chain, fetching the Circle attestation to verify the transfer, and completing the transfer on the destination chain +### Handling Variable-Length Fields - - **Automated transfers** - automatic transfers simplify the process by handling Circle attestations and finalization for you. With Wormhole's automated relaying, you only need to initiate the transfer, and the rest is managed for you +One relevant aspect of Wormhole SDK's layout system is the ability to handle variable-length fields, such as arrays and length-prefixed byte sequences. -## Prerequisites +For instance, if you want to serialize or deserialize a message where the length of the content isn't known beforehand, you can define a layout item with a `lengthSize` field. -Before you begin, ensure you have the following: +```typescript +{ name: 'message', binary: 'bytes', lengthSize: 4 } +``` - - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine - - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally - - [USDC tokens](https://faucet.circle.com/){target=\_blank} on supported chains. This tutorial uses Avalanche and Sepolia as examples - - A wallet with a private key, funded with native tokens (Testnet or Mainnet) for gas fees +This tells the SDK to read or write the message's length (in 4 bytes) and then handle the content. -## Supported Chains +## Nested Layouts and Strong Typing -The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains in the Wormhole SDK [GitHub repository](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/5810ebbd3635aaf1b5ab675da3f99f62aec2210f/core/base/src/constants/circle.ts#L14-L30){target=_blank}, which covers both Testnet and Mainnet environments. +The Wormhole SDK simplifies handling complex structures with nested layouts and strong typing. Nested layouts clearly represent hierarchical data, while strong typing ensures data consistency and catches errors during development. -## Project Setup +### Nested Layout -In this section, you'll set up your project for transferring USDC across chains using Wormhole's SDK and Circle's CCTP. We’ll guide you through initializing the project, installing dependencies, and preparing your environment for cross-chain transfers. +In complex protocols, layouts can contain nested structures. Nested layouts become relevant here, allowing you to represent hierarchical data (such as transactions or multi-part messages) in a structured format. -1. **Initialize the project** - start by creating a new directory for your project and initializing it with `npm`, which will create the `package.json` file for your project +Refer to the following nested layout where a message contains nested fields: - ```bash - mkdir cctp-circle - cd cctp-circle - npm init -y - ``` +```typescript +const nestedLayout = [ + { + name: 'source', + binary: 'bytes', + layout: [ + { name: 'chainId', binary: 'uint', size: 2 }, + { name: 'sender', binary: 'bytes', size: 32 }, + ], + }, + { + name: 'redeemer', + binary: 'bytes', + layout: [ + { name: 'address', binary: 'bytes', size: 32 }, + { name: 'message', binary: 'bytes', lengthSize: 4 }, + ], + }, +] as const satisfies Layout; +``` -2. **Create a `.gitignore` file** - ensure your private key isn't accidentally exposed or committed to version control +In this layout: - ```bash - echo ".env" >> .gitignore - ``` + - `source` is an object with two fields: `chainId` and `sender` + - `redeemer` is another object with two fields: `address` and a length-prefixed `message` -3. **Install dependencies** - install the required dependencies, including the Wormhole SDK and helper libraries +### Strong Typing - ```bash - npm install @wormhole-foundation/sdk dotenv - ``` +One of the benefits of using the Wormhole SDK in TypeScript is its support for strong typing. This ensures that serialized and deserialized data conform to expected structures, reducing errors during development by enforcing type checks at compile time. -4. **Set up environment variables** - to securely store your private key, create a `.env` file in the root of your project +Using TypeScript, the `LayoutToType` utility provided by the SDK automatically generates a strongly typed structure based on the layout: - ```bash - touch .env - ``` +```typescript +type NestedMessage = LayoutToType; +``` - Inside the `.env` file, add your private key +This ensures that when you serialize or deserialize data, it matches the expected structure. - ```env - ETH_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" - SOL_PRIVATE_KEY="INSERT_YOUR_PRIVATE_KEY" - ``` +```typescript +const message: NestedMessage = { + source: { + chainId: 6, + sender: new Uint8Array(32), + }, + redeemer: { + address: new Uint8Array(32), + message: new Uint8Array([0x01, 0x02, 0x03]), + }, +}; +``` - !!! note - Ensure your private key contains USDC funds and native tokens for gas on both the source and destination chains. +Attempting to assign data of incorrect types will result in a compile-time error. The Wormhole SDK's layout system enforces strong types, reducing runtime errors and improving code reliability. -5. **Create a `helpers.ts` file** - to simplify the interaction between chains, create a file to store utility functions for fetching your private key, setting up signers for different chains, and managing transaction relays +### Serialization and Deserialization with Nested Layouts - 1. Create the helpers file +You can serialize and deserialize nested structures in the same way as simpler layouts: - ```bash - mkdir helpers - touch helpers/helpers.ts - ``` +```typescript +const serializedNested = serializeLayout(nestedLayout, message); +const deserializedNested = deserializeLayout(nestedLayout, serializedNested); +``` - 2. Open the `helpers.ts` file and add the following code +Strong typing in TypeScript ensures that the message object conforms to the nested layout structure. This reduces the risk of data inconsistency during cross-chain communication. - ```typescript - import { - ChainAddress, - ChainContext, - Network, - Signer, - Wormhole, - Chain, -} from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { config } from 'dotenv'; -config(); +## Commonly Used Layouts -export interface SignerStuff { - chain: ChainContext; - signer: Signer; - address: ChainAddress; -} +The Wormhole SDK includes predefined layouts frequently used in cross-chain messaging. These layouts are optimized for standard fields such as chain IDs, addresses, and signatures. You can explore the complete set of predefined layouts in the [`layout-items` directory](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/layout-items){target=\_blank} of the Wormhole SDK. -// Function to fetch environment variables (like your private key) -function getEnv(key: string): string { - const val = process.env[key]; - if (!val) throw new Error(`Missing environment variable: ${key}`); - return val; -} +### Chain ID Layouts -// Signer setup function for different blockchain platforms -export async function getSigner( - chain: ChainContext -): Promise<{ - chain: ChainContext; - signer: Signer; - address: ChainAddress; -}> { - let signer: Signer; - const platform = chain.platform.utils()._platform; +Chain ID layouts in the Wormhole SDK derive from a common foundation: `chainItemBase`. This structure defines the binary representation of a chain ID as a 2-byte unsigned integer, ensuring consistency across serialization and deserialization processes. - switch (platform) { - case 'Solana': - signer = await ( - await solana() - ).getSigner(await chain.getRpc(), getEnv('SOL_PRIVATE_KEY')); - break; - case 'Evm': - signer = await ( - await evm() - ).getSigner(await chain.getRpc(), getEnv('ETH_PRIVATE_KEY')); - break; - default: - throw new Error('Unsupported platform: ' + platform); - } +#### Base Structure - return { - chain, - signer: signer as Signer, - address: Wormhole.chainAddress(chain.chain, signer.address()), - }; -} - - ``` +This simple structure is the blueprint for more specific layouts by standardizing the binary format and size. + +```typescript +const chainItemBase = { binary: 'uint', size: 2 } as const; +``` - - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file - - **`getSigner`** - based on the chain you're working with (EVM, Solana, etc.), this function retrieves a signer for that specific platform. The signer is responsible for signing transactions and interacting with the blockchain. It securely uses the private key stored in your `.env` file +#### Dynamic Chain ID Layout -6. **Create the main script** - create a new file named `manual-transfer.ts` to hold your script for transferring USDC across chains +The dynamic chain ID layout, [`chainItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/chain.ts#L13-L40){target=\_blank}, extends `chainItemBase` by adding flexible custom conversion logic. It enables runtime validation of chain IDs, supports optional null values, and restricts chain IDs to a predefined set when needed. - 1. Create the `manual-transfer.ts` file in the `src` directory +```typescript +export const chainItem = < + const C extends readonly Chain[] = typeof chains, + const N extends boolean = false, +>(opts?: { + allowedChains?: C; + allowNull?: N; +}) => + ({ + ...chainItemBase, // Builds on the base structure + custom: { + to: (val: number): AllowNull => { ... }, + from: (val: AllowNull): number => { ... }, + }, + }); +``` - ```bash - touch src/manual-transfer.ts - ``` +This layout is versatile. It allows the serialization of human-readable chain names (e.g., `Ethereum`) to numeric IDs (e.g., `1`) and vice versa. This is particularly useful when working with dynamic configurations or protocols supporting multiple chains. - 2. Open the `manual-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files +#### Fixed Chain ID Layout - ```typescript - import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { getSigner } from './helpers/helpers'; - ``` +The fixed chain ID layout, [`fixedChainItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/chain.ts#L42-L49){target=\_blank}, is more rigid. It also extends `chainItemBase`, but the custom field is hardcoded for a single chain. This eliminates runtime validation and enforces strict adherence to a specific chain. - - **`evm`** - this import is for working with EVM-compatible chains, like Avalanche, Ethereum, Base Sepolia, and more - - **`solana`** - this adds support for Solana, a non-EVM chain - - **`getSigner`** - utility function from the helper file that retrieves the signer to sign transactions +```typescript +export const fixedChainItem = (chain: C) => ({ + ...chainItemBase, // Builds on the base structure + custom: { + to: chain, + from: chainToChainId(chain), + }, +}); + +``` -## Manual Transfers +This layout allows developers to efficiently serialize and deserialize messages involving a single, fixed chain ID. -In a manual USDC transfer, you perform each step of the cross-chain transfer process individually. This approach allows for greater control and flexibility over how the transfer is executed, which can be helpful in scenarios where you need to customize certain aspects of the transfer, such as gas management, specific chain selection, or signing transactions manually. +### Address Layout -This section will guide you through performing a manual USDC transfer across chains using the Wormhole SDK and Circle’s CCTP. +The Wormhole SDK uses a Universal Address Layout to serialize and deserialize blockchain addresses into a standardized format. This layout ensures that addresses are always represented as fixed 32-byte binary values, enabling seamless cross-chain communication. -### Set Up the Transfer Environment +#### Base Structure -#### Configure Transfer Details +The [`universalAddressItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/universalAddress.ts#L7-L14){target=\_blank} defines the layout for addresses. It uses the binary type bytes and enforces a fixed size of 32 bytes for consistency. -Before initiating a cross-chain transfer, you must set up the chain context and signers for both the source and destination chains. +```typescript +export const universalAddressItem = { + binary: 'bytes', + size: 32, + custom: { + to: (val: Uint8Array): UniversalAddress => new UniversalAddress(val), + from: (val: UniversalAddress): Uint8Array => val.toUint8Array(), + } satisfies CustomConversion, +} as const satisfies LayoutItem; + +``` -1. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM and Solana) to support. This allows us to interact with both EVM-compatible chains like Avalanche and non-EVM chains like Solana if needed +This layout ensures consistent address handling by defining the following: - ```typescript - const wh = await wormhole('Testnet', [evm, solana]); - ``` - - !!! note - You can replace `'Testnet'` with `'Mainnet'` if you want to perform transfers on Mainnet. + - **Serialization** - converts a high-level `UniversalAddress` object into raw binary (32 bytes) for efficient storage or transmission + - **Deserialization** - converts raw binary back into a `UniversalAddress` object, enabling further interaction in a human-readable or programmatic format -2. **Set up source and destination chains** - specify the source chain (Avalanche) and the destination chain (Sepolia) using the `getChain` method. This allows us to define where to send the USDC and where to receive them +### Signature Layout - ```typescript - const rcvChain = wh.getChain('Sepolia'); - ``` +In the Wormhole SDK, the Signature Layout defines how to serialize and deserialize cryptographic signatures. These signatures verify message authenticity and ensure data integrity, particularly in Guardian-signed VAAs. -3. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains +#### Base Structure - ```typescript - const destination = await getSigner(rcvChain); - ``` +The `signatureLayout` specifies the binary structure of a secp256k1 signature. It divides the signature into three components: -4. **Define the transfer amount** - the amount of USDC to transfer is specified. In this case, we're transferring 0.1 USDC, which is parsed and converted into the base units expected by the Wormhole SDK +```typescript +const signatureLayout = [ + { name: 'r', binary: 'uint', size: 32 }, + { name: 's', binary: 'uint', size: 32 }, + { name: 'v', binary: 'uint', size: 1 }, +] as const satisfies Layout; +``` - ```typescript - - ``` +This layout provides a clear binary format for the secp256k1 signature, making it efficient to process within the Wormhole protocol. -5. **Set transfer mode** - we specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself +#### Layout with Custom Conversion - ```typescript - - ``` +The [`signatureItem`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/layout-items/signature.ts#L15-L22){target=\_blank} builds upon the `signatureLayout` by adding custom conversion logic. This conversion transforms raw binary data into a high-level `Signature` object and vice versa. -#### Initiate the Transfer +```typescript +export const signatureItem = { + binary: 'bytes', + layout: signatureLayout, + custom: { + to: (val: LayoutToType) => + new Signature(val.r, val.s, val.v), + from: (val: Signature) => ({ r: val.r, s: val.s, v: val.v }), + } satisfies CustomConversion, Signature>, +} as const satisfies BytesLayoutItem; + +``` -To begin the manual transfer process, you first need to create the transfer object and then manually initiate the transfer on the source chain. +The `custom` field ensures seamless integration of raw binary data with the `Signature` class, encapsulating signature-specific logic. -1. **Create the Circle transfer object** - the `wh.circleTransfer()` function creates an object with the transfer details, such as the amount of USDC, the source and destination addresses, and the mode. However, this does not initiate the transfer itself +## Advanced Use Cases - ```typescript - amt, - source.address, - destination.address, - automatic - ); - ``` +The Wormhole SDK’s layout system is designed to handle various data structures and serialization needs. This section will explore more advanced use cases, such as handling conditional data structures, fixed conversions, and optimizing serialization performance. -2. **Start the transfer** - the `initiateTransfer` function sends the transaction on the source chain. It involves signing and sending the transaction using the source signer. This will return a list of transaction IDs (`srcTxIds`) that you can use to track the transfer +???- code "Switch Statements for Conditional Layouts" + + In some cases, the structure of serialized data might change based on a specific field, such as a payload ID. The switch layout type conditionally defines layouts based on a value. + + For example, different message types can be identified using a payload ID, and the layout for each message can be determined at runtime: ```typescript - console.log(`Started Transfer: `, srcTxids); + const switchLayout = { + binary: 'switch', + idSize: 1, // size of the payload ID + idTag: 'messageType', // tag to identify the type of message + layouts: [ + [[1, 'messageType1'], fillLayout], // layout for type 1 + [[2, 'messageType2'], fastFillLayout], // layout for type 2 + ], +} as const satisfies Layout; ``` -#### Fetch the Circle Attestation (VAA) + The switch statement helps developers parse multiple payload types using the same structure, depending on a control field like an ID. -Once you initialize the transfer on the source chain, you must fetch the VAA from Circle. The VAA serves as cryptographic proof that CCTP has successfully recognized the transfer. The transfer cannot be completed on the destination chain until this attestation is fetched. +???- code "Fixed Conversions and Omitted Fields" + + Fixed conversions and omitted fields allow developers to handle known, static data without including it in every serialization or deserialization operation. For instance, when specific fields in a layout always hold a constant value, they can be omitted from the deserialized object. + **Example: Fixed Conversion** -1. **Set a timeout** - fetching the attestation can take some time, so setting a timeout is common. In this example, we set the timeout to 60 seconds + In some cases, a field may always contain a predefined value. The layout system supports fixed conversions, allowing developers to “hard-code” these values: ```typescript - + const fixedConversionLayout = { + binary: 'uint', + size: 2, + custom: { + to: 'Ethereum', + from: chainToChainId('Ethereum'), + }, +} as const satisfies Layout; ``` -2. **Fetch the attestation** - after initiating the transfer, you can use the `fetchAttestation()` function to retrieve the VAA. This function will wait until the attestation is available or you reach the specified timeout + **Example: Omitted Fields** + + Omitted fields are useful for handling padding or reserved fields that do not carry meaningful information and can safely be excluded from the deserialized output: ```typescript - console.log(`Got Attestation: `, attestIds); + const omittedFieldLayout = [ + { name: 'reserved', binary: 'uint', size: 2, omit: true }, +] as const satisfies Layout; ``` - The `attestIds` will contain the details of the fetched attestation, which Wormhole uses to complete the transfer on the destination chain + In this example, `reserved` is a padding field with a fixed, non-dynamic value that serves no functional purpose. It is omitted from the deserialized result but still considered during serialization to maintain the correct binary format. -#### Complete the Transfer on the Destination Chain + Only fields with a fixed, known value, such as padding or reserved fields, should be marked as `omit: true`. Fields with meaningful or dynamic information, such as `sourceChain` or `version`, must remain in the deserialized structure to ensure data integrity and allow seamless round-trip conversions between serialized and deserialized representations. -Once you fetch the VAA correctly, the final step is to complete the transfer on the destination chain (Sepolia in this example). This involves redeeming the VAA, which moves the USDC from Circle's custody onto the destination chain. +## Integration with Wormhole Protocol -Use the `completeTransfer()` function to finalize the transfer on the destination chain. This requires the destination signer to sign and submit the transaction to the destination chain +The layout system facilitates seamless interaction with the Wormhole protocol, mainly when dealing with VAAs. These cross-chain messages must be serialized and deserialized to ensure they can be transmitted and processed accurately across different chains. -```typescript -console.log(`Completed Transfer: `, dstTxids); +### VAAs and Layouts - console.log('Circle Transfer status: ', xfer); +VAAs are the backbone of Wormhole’s cross-chain communication. Each VAA is a signed message encapsulating important information such as the originating chain, the emitter address, a sequence number, and Guardian signatures. The Wormhole SDK leverages its layout system to define, serialize, and deserialize VAAs, ensuring data integrity and chain compatibility. - process.exit(0); -``` +#### Base VAA Structure -The `dstTxIds` will hold the transaction IDs for the transfer on the destination chain, confirming that the transfer has been completed +The Wormhole SDK organizes the VAA structure into three key components: -You can find the full code for the manual USDC transfer script below: + - [**Header**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L37-L41){target=\_blank} - contains metadata such as the Guardian set index and an array of Guardian signatures + - [**Envelope**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} - includes chain-specific details such as the emitter chain, address, sequence, and [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} + - **Payload** - provides application-specific data, such as the actual message or operation being performed -???- code "`manual-transfer.ts`" - ```typescript - import { wormhole } from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { getSigner } from './helpers/helpers'; +**Header layout:** -(async function () { - const wh = await wormhole('Testnet', [evm, solana]); +```typescript +const guardianSignatureLayout = [ + { name: 'guardianIndex', binary: 'uint', size: 1 }, + { name: 'signature', ...signatureItem }, +] as const satisfies Layout; - // Set up source and destination chains - const sendChain = wh.getChain('Avalanche'); - const rcvChain = wh.getChain('Sepolia'); +export const headerLayout = [ + { name: 'version', binary: 'uint', size: 1, custom: 1, omit: true }, + { name: 'guardianSet', ...guardianSetItem }, + { + name: 'signatures', + binary: 'array', + lengthSize: 1, + layout: guardianSignatureLayout, + }, +] as const satisfies Layout; +``` - // Configure the signers - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); +The header defines metadata for validating and processing the VAA, such as the Guardian set index and signatures. Each signature is represented using the `signatureItem` layout, ensuring consistency and compatibility across different platforms. - // Define the transfer amount (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) - const amt = 100_000n; +!!! note "Signature Standard Compliance" - const automatic = false; + The signature field uses the `signatureItem` layout, which is explicitly defined as 65 bytes. This layout is aligned with widely used standards such as EIP-2612 and Uniswap's Permit2, ensuring compatibility with cryptographic protocols and applications. - // Create the Circle transfer object - const xfer = await wh.circleTransfer( - amt, - source.address, - destination.address, - automatic - ); +**Envelope layout:** + +```typescript +export const envelopeLayout = [ + { name: 'timestamp', binary: 'uint', size: 4 }, + { name: 'nonce', binary: 'uint', size: 4 }, + { name: 'emitterChain', ...chainItem() }, + { name: 'emitterAddress', ...universalAddressItem }, + { name: 'sequence', ...sequenceItem }, + { name: 'consistencyLevel', binary: 'uint', size: 1 }, +] as const satisfies Layout; +``` + +The envelope encapsulates the VAA's core message data, including chain-specific information like the emitter address and sequence number. This structured layout ensures that the VAA can be securely transmitted across chains. - console.log('Circle Transfer object created:', xfer); +**Payload Layout:** - // Initiate the transfer on the source chain (Avalanche) - console.log('Starting Transfer'); - const srcTxids = await xfer.initiateTransfer(source.signer); - console.log(`Started Transfer: `, srcTxids); +The Payload contains the user-defined data specific to the application or protocol, such as a token transfer message, governance action, or other cross-chain operation. The layout of the payload is dynamic and depends on the payload type, identified by the `payloadLiteral` field. - // Wait for Circle Attestation (VAA) - const timeout = 60 * 1000; // Timeout in milliseconds (60 seconds) - console.log('Waiting for Attestation'); - const attestIds = await xfer.fetchAttestation(timeout); - console.log(`Got Attestation: `, attestIds); +```typescript +const examplePayloadLayout = [ + { name: 'type', binary: 'uint', size: 1 }, + { name: 'data', binary: 'bytes', lengthSize: 2 }, +] as const satisfies Layout; +``` - // Complete the transfer on the destination chain (Sepolia) - console.log('Completing Transfer'); - const dstTxids = await xfer.completeTransfer(destination.signer); - console.log(`Completed Transfer: `, dstTxids); +This example demonstrates a payload containing: - console.log('Circle Transfer status: ', xfer); + - A type field specifying the operation type (e.g., transfer or governance action) + - A data field that is length-prefixed and can store operation-specific information - process.exit(0); -})(); - ``` +Dynamic payload layouts are selected at runtime using the `payloadLiteral` field, which maps to a predefined layout in the Wormhole SDK. -### Run Manual Transfer +**Combined Base Layout:** -To execute the manual transfer script, you can use `ts-node` to run the TypeScript file directly +The base VAA layout combines the header, envelope, and dynamically selected payload layout: -```bash -npx ts-node src/manual-transfer.ts +```typescript +export const baseLayout = [...headerLayout, ...envelopeLayout] as const; ``` -This will initiate the USDC transfer from the source chain (Avalanche) and complete it on the destination chain (Sepolia). +At runtime, the payload layout is appended to the `baseLayout` to form the complete structure. -You can monitor the status of the transaction on the [Wormhole explorer](https://wormholescan.io/){target=\_blank}. +#### Serializing VAA Data -### Complete Partial Transfer +The Wormhole SDK provides the [`serialize`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/functions.ts#L48-L54){target=\_blank} function to serialize a VAA message. This function combines the base layout (header and envelope) with the appropriate payload layout, ensuring the message’s format is correct for transmission across chains. -In some cases, a manual transfer might start but not finish—perhaps the user terminates their session, or there's an issue before the transfer can be completed. The Wormhole SDK allows you to reconstitute the transfer object from the transaction hash on the source chain. +```typescript +import { serialize } from '@wormhole-foundation/sdk-core/vaa/functions'; -This feature is handy for recovering an incomplete transfer or when debugging. +const vaaData = { + guardianSet: 1, + signatures: [{ guardianIndex: 0, signature: new Uint8Array(65).fill(0) }], + timestamp: 1633000000, + nonce: 42, + emitterChain: 2, // Ethereum + emitterAddress: new Uint8Array(32).fill(0), + sequence: BigInt(1), + consistencyLevel: 1, + payloadLiteral: 'SomePayloadType', + payload: { key: 'value' }, +}; -Here’s how you can complete a partial transfer using just the source chain and transaction hash: +const serializedVAA = serialize(vaaData); +``` -```typescript -wh, - { - chain: 'Avalanche', - txid: '0x6b6d5f101a32aa6d2f7bf0bf14d72bfbf76a640e1b2fdbbeeac5b82069cda4dd', - }, - timeout - ); +???- note "How does it work?" - const dstTxIds = await xfer.completeTransfer(destination.signer); - console.log('Completed transfer: ', dstTxIds); -``` + Internally, the serialize function dynamically combines the `baseLayout` (header and envelope) with the payload layout defined by the `payloadLiteral`. The complete layout is then passed to the `serializeLayout` function, which converts the data into binary format. -You will need to provide the below requirements to complete the partial transfer: + ```typescript + const layout = [ + ...baseLayout, // Header and envelope layout + payloadLiteralToPayloadItemLayout(vaa.payloadLiteral), // Payload layout +] as const; -- **Transaction ID (`txId`)** - the transaction hash from the source chain where the transfer was initiated -- **Signer for the destination chain (`destination.signer`)** - the wallet or private key that can authorize and complete the transfer on the destination chain. This signer is the same as the `destination.signer` defined in the manual transfer setup +return serializeLayout(layout, vaa as LayoutToType); + + ``` -This allows you to resume the transfer process by rebuilding the transfer object and completing it on the destination chain. It's especially convenient when debugging or handling interrupted transfers. +#### Deserializing VAA Data -You can find the full code for the manual USDC transfer script below: +The Wormhole SDK provides the [`deserialize`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/vaa/functions.ts#L162-L200){target=\_blank} function to parse a VAA from its binary format back into a structured object. This function uses the `baseLayout` and payload discriminator logic to ensure the VAA is correctly interpreted. -??? code "`partial-transfer.ts`" - ```typescript - import { CircleTransfer, wormhole } from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { getSigner } from '../helpers/helpers'; +```typescript +import { deserialize } from '@wormhole-foundation/sdk-core/vaa/functions'; -(async function () { - // Initialize the Wormhole object for the Testnet environment and add supported chains (evm and solana) - const wh = await wormhole('Testnet', [evm, solana]); +const serializedVAA = new Uint8Array([ + /* Serialized VAA binary data */ +]); - // Grab chain Contexts -- these hold a reference to a cached rpc client - const rcvChain = wh.getChain('Sepolia'); +const vaaPayloadType = 'SomePayloadType'; // The payload type expected for this VAA +const deserializedVAA = deserialize(vaaPayloadType, serializedVAA); +``` - // Get signer from local key - const destination = await getSigner(rcvChain); +???- note "How does it work?" - const timeout = 60 * 1000; // Timeout in milliseconds (60 seconds) + Internally, the `deserialize` function uses the `baseLayout` (header and envelope) to parse the main VAA structure. It then identifies the appropriate payload layout using the provided payload type or discriminator. - // Rebuild the transfer from the source txid - const xfer = await CircleTransfer.from( - wh, - { - chain: 'Avalanche', - txid: '0x6b6d5f101a32aa6d2f7bf0bf14d72bfbf76a640e1b2fdbbeeac5b82069cda4dd', - }, - timeout - ); + ```typescript + const [header, envelopeOffset] = deserializeLayout(headerLayout, data, { + consumeAll: false, +}); - const dstTxIds = await xfer.completeTransfer(destination.signer); - console.log('Completed transfer: ', dstTxIds); +const [envelope, payloadOffset] = deserializeLayout(envelopeLayout, data, { + offset: envelopeOffset, + consumeAll: false, +}); - console.log('Circle Transfer status: ', xfer); +const [payloadLiteral, payload] = + typeof payloadDet === 'string' + ? [ + payloadDet as PayloadLiteral, + deserializePayload(payloadDet as PayloadLiteral, data, payloadOffset), + ] + : deserializePayload( + payloadDet as PayloadDiscriminator, + data, + payloadOffset + ); - process.exit(0); -})(); +return { + ...header, + ...envelope, + payloadLiteral, + payload, +} satisfies VAA; ``` -## Automatic Transfers +### Registering Custom Payloads -The automatic transfer process simplifies the steps by automating the attestation fetching and transfer completion. All you need to do is initiate the transfer. +In the Wormhole SDK, payloads rely on layouts to define their binary structure, ensuring consistency and type safety across protocols. Custom payloads extend this functionality, allowing developers to handle protocol-specific features or unique use cases. -### Set Up the Transfer Environment +To learn how to define and register payloads using layouts, refer to the [Building Protocols and Payloads](/docs/tools/typescript-sdk/guides/protocols-payloads/){target=\_blank} page for a detailed guide. -#### Configure Transfer Details +## Common Pitfalls & Best Practices -The setup for automatic transfers is similar to manual transfers, with the key difference being that the `automatic` flag is `true`. This indicates that Wormhole will handle the attestation and finalization steps for you +When working with the Wormhole SDK layout system, it's important to be aware of a few common issues that can arise. Below are some pitfalls to avoid and best practices to ensure smooth integration. -```typescript +### Pitfalls to Avoid -``` +#### Defining Sizes for Data Types -#### Initiate the Transfer +When defining sizes for each data type, make sure to match the actual data length to the specified size to prevent serialization and deserialization errors: -The transfer process is the same as that for manual transfers. You create the transfer object and then start the transfer on the source chain + - **`uint` and `int`** - the specified size must be large enough to accommodate the data value. For instance, storing a value greater than 255 in a single byte (`uint8`) will fail since it exceeds the byte’s capacity. Similarly, an undersized integer (e.g., specifying 2 bytes for a 4-byte integer) can lead to data loss or deserialization failure + - **`bytes`** - the data must match the specified byte length in the layout. For example, defining a field as 32 bytes (`size: 32`) requires the provided data to be exactly 32 bytes long; otherwise, serialization will fail ```typescript -amt, - source.address, - destination.address, - automatic - ); +// Pitfall: Mismatch between the size of data and the defined size in the layout +{ name: 'orderSender', binary: 'bytes', size: 32 } +// If the provided data is not exactly 32 bytes, this will fail ``` -#### Log Transfer Details +#### Incorrectly Defined Arrays -After initiating the transfer, you can log the transaction IDs for both the source and destination chains. This will help you track the progress of the transfer +Arrays can be fixed-length or length-prefixed, so it’s important to define them correctly. Fixed-length arrays must match the specified length, while length-prefixed arrays need a `lengthSize` field. ```typescript -console.log(`Started Transfer: `, srcTxids); - - process.exit(0); +// Pitfall: Array length does not match the expected size +{ name: 'redeemerMessage', binary: 'bytes', lengthSize: 4 } ``` -You can find the full code for the automatic USDC transfer script below: - -??? code "`automatic-transfer.ts`" - ```typescript - import { wormhole } from '@wormhole-foundation/sdk'; -import evm from '@wormhole-foundation/sdk/evm'; -import solana from '@wormhole-foundation/sdk/solana'; -import { getSigner } from '../helpers/helpers'; - -(async function () { - // Initialize the Wormhole object for the Testnet environment and add supported chains (evm and solana) - const wh = await wormhole('Testnet', [evm, solana]); - - // Set up source and destination chains - const sendChain = wh.getChain('Avalanche'); - const rcvChain = wh.getChain('Sepolia'); - - // Configure the signers - const source = await getSigner(sendChain); - const destination = await getSigner(rcvChain); - - // Define the transfer amount (in the smallest unit, so 0.1 USDC = 100,000 units assuming 6 decimals) - const amt = 100_000_001n; - - const automatic = true; - - // Create the Circle transfer object (USDC-only) - const xfer = await wh.circleTransfer( - amt, - source.address, - destination.address, - automatic - ); +### Best Practices - console.log('Circle Transfer object created:', xfer); +These best practices and common pitfalls can help prevent bugs and improve the reliability of your implementation when working with layouts in the Wormhole SDK. - // Initiate the transfer on the source chain (Avalanche) - console.log('Starting Transfer'); - const srcTxids = await xfer.initiateTransfer(source.signer); - console.log(`Started Transfer: `, srcTxids); +#### Reuse Predefined Layout Items - process.exit(0); -})(); - ``` +Rather than defining sizes or types manually, reuse the predefined layout items provided by the Wormhole SDK. These items ensure consistent formatting and enforce strong typing. -### Run Automatic Transfer +For instance, use the `chainItem` layout for chain IDs or `universalAddressItem` for blockchain addresses: -Assuming you have created a new `automatic-transfer.ts` file for automatic transfers under the `src` directory, use the following command to run it with `ts-node`: +```typescript +import { + chainItem, + universalAddressItem, +} from '@wormhole-foundation/sdk-core/layout-items'; -```bash -npx ts-node src/automatic-transfer.ts +const exampleLayout = [ + { name: 'sourceChain', ...chainItem() }, // Use predefined chain ID layout + { name: 'senderAddress', ...universalAddressItem }, // Use universal address layout +] as const; ``` -The automatic relayer will take care of fetching the attestation and completing the transfer for you. +By leveraging predefined layout items, you reduce redundancy, maintain consistency, and ensure compatibility with Wormhole’s standards. -## Resources +#### Use Class Instances -If you'd like to explore the complete project or need a reference while following this tutorial, you can find the complete codebase in [Wormhole's demo GitHub repository](https://github.com/wormhole-foundation/demo-cctp-transfer){target=\_blank}. The repository includes all the example scripts and configurations needed to perform USDC cross-chain transfers, including manual, automatic, and partial transfers using the Wormhole SDK and Circle's CCTP. +Whenever possible, convert deserialized data into higher-level class instances. This makes it easier to validate, manipulate, and interact with structured data. For example, the [`UniversalAddress`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/definitions/src/universalAddress.ts#L17-L59){target=\_blank} class ensures consistent address handling: + +```typescript +import { UniversalAddress } from '@wormhole-foundation/sdk-core'; -## Conclusion +const deserializedAddress = new UniversalAddress(someBinaryData); +``` -In this tutorial, you’ve gained hands-on experience with Circle’s CCTP and the Wormhole SDK. You’ve learned to perform manual and automatic USDC transfers across multiple chains and recover partial transfers if needed. +Focusing on reusing predefined layout items and converting deserialized data into higher-level abstractions can ensure a more robust and maintainable implementation. -By following these steps, you've learned how to: +#### Consistent Error Handling -- Set up cross-chain transfers for native USDC between supported chains -- Handle both manual and automatic relaying of transactions -- Recover and complete incomplete transfers using the transaction hash and the destination chain’s signer ---- END CONTENT --- +Always handle errors during both serialization and deserialization. Catching exceptions allows you to log or resolve issues gracefully when working with potentially corrupted or invalid data. -Doc-Content: https://wormhole.com/docs/tutorials/wormholescan/ ---- BEGIN CONTENT --- ---- -title: Wormholescan API Tutorials -description: Explore step-by-step guides on using the Wormholescan API to fetch VAAs, validate signatures, check redemption status, and process cross-chain transactions. ---- +```typescript +try { + const deserialized = deserializeLayout(fillLayout, data); +} catch (error) { + console.error('Deserialization failed:', error); +} +``` -# Wormholescan API +#### Leverage Reusable Layouts -Explore hands-on tutorials for using the Wormholescan API to retrieve blockchain data, track transactions, validate VAAs, check redemption status, and more. +Creating reusable layouts for commonly repeated structures improves code maintainability and reduces duplication. These layouts can represent fields or combinations of fields frequently encountered in cross-chain communication, such as chain IDs, addresses, and signatures. -## Tutorials +For example, define a reusable layout for chain IDs and addresses: -
+```typescript +const commonLayout = [ + { name: 'chainId', binary: 'uint', size: 2 }, + { name: 'address', binary: 'bytes', size: 32 }, +] as const satisfies Layout; -- :octicons-repo-16:{ .lg .middle } **Replace Outdated Signatures in VAAs** +// Reuse the common layout in different contexts +const exampleLayout = [ + ...commonLayout, + { name: 'sequence', binary: 'uint', size: 8 }, +]; +``` - --- +By abstracting common elements into a single layout, you ensure consistency across different parts of your application and simplify future updates. - Learn how to fetch VAAs, verify their validity, and replace outdated signatures using the Wormholescan API and Wormhole SDK. +## Performance Considerations - [:custom-arrow: Start tutorial](/docs/tutorials/wormholescan/replace-signatures/) +Efficient serialization and deserialization are crucial when handling large amounts of cross-chain data. Below are some strategies and best practices to ensure optimal performance when using Wormhole SDK layouts. -
+### Lazy Instantiation -## Additional Resources +Building a discriminator can be resource-intensive for complex or large datasets. The layout structures do not incur significant upfront costs, but deferring the creation of discriminators until needed can improve efficiency. -
+```typescript +const lazyDiscriminator = lazyInstantiate(() => layoutDiscriminator(layouts)); +``` -- :octicons-book-16:{ .lg .middle } **Wormholescan** +This approach ensures that discriminators are only built when required, helping to optimize performance, especially for complex or conditional layouts. - --- +## Resources - Wormholescan is a blockchain explorer for tracking transactions, VAAs, and cross-chain activity. Its API provides programmatic access to transaction data, network analytics, and more. +For further learning and practical experience, explore the following resources: - [:custom-arrow: Visit Wormholescan](https://wormholescan.io/){target=\_blank} + - **Wormhole TypeScript SDK** - the [Wormhole SDK repository](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} contains the core implementation of layouts, including predefined layout items and utilities like `serializeLayout` and `deserializeLayout` -
+ - **Layout tests repository** - for hands-on experimentation, check out this [layout package repository](https://github.com/nonergodic/layout){target=\_blank}, which provides examples and unit tests to help you better understand serialization, deserialization, and the strong typing mechanism. Running these tests locally is a great way to deepen your understanding of how layouts function in real-world scenarios --- END CONTENT --- -Doc-Content: https://wormhole.com/docs/tutorials/wormholescan/replace-signatures/ +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/guides/vaas-protocols/ --- BEGIN CONTENT --- --- -title: Replace Outdated Signatures in VAAs -description: Learn how to fetch, validate, and replace outdated signatures in Wormhole VAAs using Wormholescan and the Wormhole SDK to ensure seamless processing. +title: VAAs and Protocols +description: Understand how VAAs enable cross-chain messaging and how to handle them using Wormhole's TypeScript and Solidity SDKs. +categories: Typescript-SDK --- -# Replace Outdated Signatures in VAAs - -:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-vaa-signature-replacement){target=\_blank} +# VAAs and Protocols ## Introduction -Cross-chain transactions in Wormhole rely on [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank}, which contain signatures from a trusted set of validators called [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank}. These signatures prove that the network approved an action, such as a token transfer. - -However, the set of Guardians changes over time. If a user generates a transaction and waits too long before redeeming it, the Guardian set may have already changed. This means the VAA will contain outdated signatures from Guardians, who are no longer part of the network, causing the transaction to fail. - -Instead of discarding these VAAs, we can fetch updated signatures and replace the outdated ones to ensure smooth processing. - -In this tutorial, you'll build a script from scratch to: - -- Fetch a VAA from [Wormholescan](https://wormholescan.io/#/developers/api-doc){target=\_blank} -- Validate its signatures against the latest Guardian set -- Replace outdated signatures using the [Wormhole SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} -- Output a valid VAA ready for submission +Wormhole's core functionality revolves around [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs), which are signed messages enabling secure and decentralized communication across chains. This guide focuses on their practical usage within the Wormhole ecosystem, specifically when working with protocol-specific messages in the [TypeScript](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and [Solidity](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank} SDKs. -By the end, you'll have a script that ensures VAAs remain valid and processable, avoiding transaction failures. +For deeper insights into serialization, deserialization, and protocol design, refer to: -## Prerequisites +- [Data Layouts](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank} for serialization concepts +- [Building Protocols and Payloads](/docs/tools/typescript-sdk/guides/protocols-payloads/){target=\_blank} for designing custom protocol messages -Before you begin, ensure you have the following: +This guide will help you understand how to handle VAAs and protocol messages in off-chain and on-chain scenarios. - - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine - - [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed globally +## VAA Structure -## Project Setup +Understanding the structure of VAAs is fundamental to working with Wormhole's SDKs. Each section of the VAA—Header, Envelope, and Payload—serves a specific role: -In this section, you will create the directory, initialize a Node.js project, install dependencies, and configure TypeScript. +| Section | Description | +|----------|----------------------------------------------------------------------------------------------------------| +| Header | Includes the version and guardian signature information required to verify the VAA | +| Envelope | Contains metadata about the emitted message, such as the emitter chain, emitter address, and timestamp | +| Payload | Represents the actual message, in raw bytes, without a length prefix | -1. **Create the project** - set up the directory and navigate into it +The VAA's body combines the Envelope and Payload. The Wormhole Guardians signed the core data and hashed (using `keccak256`) to generate the VAA's unique identifier. - ```bash - mkdir wormhole-scan-api-demo - cd wormhole-scan-api-demo - ``` +When integrating protocols like Token Bridge or Wormhole Relayer: -2. **Initialize a Node.js project** - generate a `package.json` file +- The TypeScript SDK handles VAAs off-chain, focusing on deserialization, validation, and payload extraction before submission +- The Solidity SDK processes VAAs on-chain, using libraries like [`VaaLib`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/libraries/VaaLib.sol){target=\_blank} to decode and execute protocol actions - ```bash - npm init -y - ``` +## VAAs in Protocol Contexts -3. **Set up TypeScript** - create a `tsconfig.json` file +### How VAAs Enable Protocol-Specific Messaging - ```bash - touch tsconfig.json - ``` +VAAs are the backbone of Wormhole's cross-chain communication, encapsulating critical protocol payloads that drive actions on different blockchains. Each protocol—such as [Token Bridge](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/tokenBridge){target=\_blank}, [Wormhole Relayer](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/relayer){target=\_blank}, or [Circle CCTP](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/core/definitions/src/protocols/circleBridge){target=\_blank}—uses VAAs to securely transmit its messages across chains. - Then, add the following configuration: +Examples of mapping protocols to VAAs: - ```json title="tsconfig.json" - { - "compilerOptions": { - "target": "es2016", - "module": "commonjs", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true - } -} - ``` +| Protocol | Payload Purpose | Example | +|-----------------|-----------------------------------------------------------|------------------------------------| +| Token Bridge | Transfers token data and metadata | Token transfer or redemption | +| Wormhole Relayer| Manages delivery instructions for messages across chains | Delivery fee or refund handling | +| Circle CCTP | Facilitates stablecoin mint-and-burn operations | Circle-issued stablecoin transfer | -4. **Install dependencies** - add the required packages +Each protocol integrates its payload format into the VAA structure, ensuring consistent message validation and execution across the ecosystem. - ```bash - npm install @wormhole-foundation/sdk axios web3 tsx @types/node - ``` +### TypeScript SDK: Off-Chain Handling of VAAs - - `@wormhole-foundation/sdk` - handles VAAs and cross-chain interactions - - `axios` - makes HTTP requests to the Wormholescan API - - `web3` - interacts with Ethereum transactions and contracts - - `tsx` - executes TypeScript files without compilation - - `@types/node` - provides Node.js type definitions +The TypeScript SDK is designed for off-chain operations like reading, validating, and manipulating VAAs before submitting them to a chain. Developers can easily deserialize VAAs to extract protocol payloads and prepare actions such as initiating token transfers or constructing delivery instructions. -5. **Create the project structure** - set up the required directories and files +In the example below, we use the real [`envelopeLayout`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/dd6bd2463264680597519285ff559f9e92e85ca7/core/definitions/src/vaa/vaa.ts#L44-L51){target=\_blank} from Wormhole's TS SDK to deserialize and extract essential information like the emitter chain, sequence, and [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank}: - ```bash - mkdir -p src/config && touch src/config/constants.ts src/config/layouts.ts - mkdir -p src/helpers && touch src/helpers/vaaHelper.ts - mkdir -p src/scripts && touch scripts/replaceSignatures.ts - ``` +```typescript +import { deserializeLayout } from '@wormhole-foundation/sdk-base'; +import { + universalAddressItem, + sequenceItem, +} from '@wormhole-foundation/core/layout-items/index.js'; - - **`src/config/*`** - stores public configuration variables and layouts for serializing and deserializing data structures - - **`src/helpers/*`** - contains utility functions - - **`src/scripts/*`** - contains scripts for fetching and replacing signatures +export const envelopeLayout = [ + { name: 'timestamp', binary: 'uint', size: 4 }, + { name: 'nonce', binary: 'uint', size: 4 }, + { name: 'emitterChain', binary: 'uint', size: 2 }, + { name: 'emitterAddress', ...universalAddressItem }, + { name: 'sequence', ...sequenceItem }, + { name: 'consistencyLevel', binary: 'uint', size: 1 }, +] as const satisfies Layout; -6. **Set variables** - define key constants in `src/config/constants.ts` +const encodedEnvelope = new Uint8Array([ + /* binary envelope data */ +]); +const deserializedEnvelope = deserializeLayout(envelopeLayout, encodedEnvelope); +``` - ```bash title="src/config/constants.ts" - export const RPC = 'https://ethereum-rpc.publicnode.com'; +For more details, you can refer to the [parseVAA example](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/examples/src/parseVaa.ts){target=\_blank} in the Wormhole SDK repository. -export const ETH_CORE = - '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B'.toLowerCase(); +### Solidity SDK: On-Chain Handling of VAAs -export const WORMHOLESCAN_API = 'https://api.wormholescan.io/v1'; +The Solidity SDK enables on-chain processing of VAAs directly within smart contracts. This is essential for real-time validation, decoding, and execution of protocol-specific payloads. Developers can use libraries like [`VaaLib`](https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/e19013d08d1fdf5af9e6344c637e36a270422dd9/src/libraries/VaaLib.sol){target=\_blank} to parse the VAA header and payload, ensuring the message is authentic and consistent with Wormhole's validation. -export const LOG_MESSAGE_PUBLISHED_TOPIC = - '0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2'; +Below is an example of parsing an envelope on-chain using the Solidity SDK: -export const TXS = [ - '0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367', - '0x3c989a6bb40dcd4719453fbe7bbac420f23962c900ae75793124fc9cc614368c', -]; - ``` +```solidity +// SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.19; - - **`RPC`** - endpoint for interacting with an Ethereum RPC node - - **`ETH_CORE`** - [Wormhole's Core Contract address on Ethereum](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} responsible for verifying VAAs - - **`WORMHOLESCAN_API`** - base URL for querying the Wormholescan API to fetch VAA data and Guardian sets - - **`LOG_MESSAGE_PUBLISHED_TOPIC`** - the event signature hash for `LogMessagePublished`, a Wormhole contract event that signals when a VAA has been emitted. This is used to identify relevant logs in transaction receipts - - **`TXS`** - list of example transaction hashes that will be used for testing +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; -7. **Define data structure for working with VAAs** - specify the ABI for the Wormhole Core Contract's `parseAndVerifyVM` function, which parses and verifies VAAs. Defining the data structure, also referred to as a [layout](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank}, for this function ensures accurate decoding and validation of VAAs +contract EnvelopeParser { + using VaaLib for bytes; - ```typescript title="src/config/layouts.ts" - export const PARSE_AND_VERIFY_VM_ABI = { - inputs: [{ internalType: 'bytes', name: 'encodedVM', type: 'bytes' }], - name: 'parseAndVerifyVM', - outputs: [ + function parseEnvelope( + bytes memory encodedVaa + ) + public + pure + returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel + ) { - components: [ - { internalType: 'uint8', name: 'version', type: 'uint8' }, - { internalType: 'uint32', name: 'timestamp', type: 'uint32' }, - { internalType: 'uint32', name: 'nonce', type: 'uint32' }, - { internalType: 'uint16', name: 'emitterChainId', type: 'uint16' }, - { internalType: 'bytes32', name: 'emitterAddress', type: 'bytes32' }, - { internalType: 'uint64', name: 'sequence', type: 'uint64' }, - { internalType: 'uint8', name: 'consistencyLevel', type: 'uint8' }, - { internalType: 'bytes', name: 'payload', type: 'bytes' }, - { internalType: 'uint32', name: 'guardianSetIndex', type: 'uint32' }, - { - components: [ - { internalType: 'bytes32', name: 'r', type: 'bytes32' }, - { internalType: 'bytes32', name: 's', type: 'bytes32' }, - { internalType: 'uint8', name: 'v', type: 'uint8' }, - { internalType: 'uint8', name: 'guardianIndex', type: 'uint8' }, - ], - internalType: 'struct Structs.Signature[]', - name: 'signatures', - type: 'tuple[]', - }, - { internalType: 'bytes32', name: 'hash', type: 'bytes32' }, - ], - internalType: 'struct Structs.VM', - name: 'vm', - type: 'tuple', - }, - { internalType: 'bool', name: 'valid', type: 'bool' }, - { internalType: 'string', name: 'reason', type: 'string' }, - ], - stateMutability: 'view', - type: 'function', -}; - ``` + // Skip the header and decode the envelope + uint offset = VaaLib.skipVaaHeaderMemUnchecked(encodedVaa, 0); + return VaaLib.decodeVaaEnvelopeMemUnchecked(encodedVaa, offset); + } +} +``` +--- END CONTENT --- + +Doc-Content: https://wormhole.com/docs/tools/typescript-sdk/sdk-reference/ +--- BEGIN CONTENT --- +--- +title: Wormhole TS SDK +description: Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC. +categories: Typescript-SDK +--- -## Create VAA Handling Functions +# Wormhole TypeScript SDK Reference -In this section, we'll create a series of helper functions in the `src/helpers/vaaHelper.ts` file that will retrieve and verify VAAs and fetch and replace outdated Guardian signatures to generate a correctly signed VAA. +This page covers all you need to know about the functionality offered through the Wormhole TypeScript SDK. -To get started, import the necessary dependencies: +
-```typescript title="src/helpers/vaaHelper.ts" -import { eth } from 'web3'; -import { - deserialize, - serialize, - VAA, - Signature, -} from '@wormhole-foundation/sdk'; -import { - RPC, - ETH_CORE, - LOG_MESSAGE_PUBLISHED_TOPIC, - WORMHOLESCAN_API, -} from '../config/constants'; -import { PARSE_AND_VERIFY_VM_ABI } from '../config/layouts'; -``` +- :octicons-download-16:{ .lg .middle } **Installation** -### Fetch a VAA ID from a Transaction + --- -To retrieve a VAA, we first need to get its VAA ID from a transaction hash. This ID allows us to fetch the full VAA later. -The VAA ID is structured as follows: + Find installation instructions for both the meta package and installing specific, individual packages. -```bash -chain/emitter/sequence -``` + [:custom-arrow: Install the SDK](/docs/tools/typescript-sdk/get-started/#install-the-sdk) - - `chain` - the [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} (Ethereum is 2) - - `emitter` - the contract address that emitted the VAA - - `sequence` - a unique identifier for the event +- :octicons-code-square-16:{ .lg .middle } **TSdoc for SDK** -We must assemble the ID correctly since this is the format the Wormholescan API expects when querying VAAs. + --- -Follow the below steps to process the transaction logs and construct the VAA ID: + Review the TSdoc for the Wormhole TypeScript SDK for a detailed look at available methods, classes, interfaces, and definitions. -1. **Get the transaction receipt** - iterate over the array of transaction hashes and fetch the receipt to access its logs + [:custom-arrow: View the TSdoc on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank} -2. **Find the Wormhole event** - iterate over the transaction logs and check for events emitted by the Wormhole Core contract. Look specifically for `LogMessagePublished` events, which indicate a VAA was created +- :octicons-code-square-16:{ .lg .middle } **Source Code** -3. **Extract the emitter and sequence number** - if a matching event is found, extract the emitter address from `log.topics[1]` and remove the `0x` prefix. Then, the sequence number from `log.data` is extracted, converting it from hex to an integer + --- -4. **Construct the VAA ID** - format the extracted data in `chain/emitter/sequence` format + Want to go straight to the source? Check out the TypeScript SDK GitHub repository. + + [:custom-arrow: View GitHub Repository](https://github.com/wormhole-foundation/wormhole-sdk-ts/){target=\_blank} -```typescript title="src/helpers/vaaHelper.ts" -const vaaIds: string[] = []; +
- for (const tx of txHashes) { - try { - const result = ( - await axios.post(RPC, { - jsonrpc: '2.0', - id: 1, - method: 'eth_getTransactionReceipt', - params: [tx], - }) - ).data.result; +!!! warning + This package is a work in progress. The interface may change, and there are likely bugs. Please [report any issues](https://github.com/wormhole-foundation/connect-sdk/issues){target=\_blank} you find. - if (!result) - throw new Error(`Unable to fetch transaction receipt for ${tx}`); +## Concepts - for (const log of result.logs) { - if ( - log.address === ETH_CORE && - log.topics?.[0] === LOG_MESSAGE_PUBLISHED_TOPIC - ) { - const emitter = log.topics[1].substring(2); - const seq = BigInt(log.data.substring(0, 66)).toString(); - vaaIds.push(`2/${emitter}/${seq}`); - } - } - } catch (error) { - console.error(`Error processing ${tx}:`, error); - } - } +Understanding key Wormhole concepts—and how the SDK abstracts them—will help you use the tools more effectively. The following sections cover platforms, chain contexts, addresses, signers, and protocols, explaining their roles in Wormhole and how the SDK simplifies working with them. - return vaaIds; -} -``` +### Platforms -???- code "Try it out: VAA ID retrieval" - If you want to try out the function before moving forward, create a test file inside the `test` directory: +The SDK includes `Platform` modules, which create a standardized interface for interacting with the chains of a supported platform. The contents of a module vary by platform but can include: - 1. **Create the directory and file** - add a script to call `fetchVaaId` and print the result +- [Protocols](#protocols) preconfigured to suit the selected platform +- Definitions and configurations for types, signers, addresses, and chains +- Helpers configured for dealing with unsigned transactions on the selected platform - ```bash - mkdir -p test - touch test/fetchVaaId.run.ts - ``` - 2. **Add the function call** +These modules expose key functions and types from the native ecosystem, reducing the need for full packages and keeping dependencies lightweight. - ```typescript title="test/fetchVaaId.run.ts" - import { fetchVaaId } from '../src/helpers/vaaHelper'; -import { TXS } from '../src/config/constants'; +??? interface "Supported platform modules" -const testFetchVaaId = async () => { - for (const tx of TXS) { - const vaaIds = await fetchVaaId([tx]); + | Platform | Installation Command | + |----------|----------------------------------------------------| + | EVM |
```@wormhole-foundation/sdk-evm```
| + | Solana |
```@wormhole-foundation/sdk-solana```
| + | Algorand |
```@wormhole-foundation/sdk-algorand```
| + | Aptos |
```@wormhole-foundation/sdk-aptos```
| + | Cosmos |
```@wormhole-foundation/sdk-cosmwasm```
| + | Sui |
```@wormhole-foundation/sdk-sui```
| - if (vaaIds.length > 0) { - console.log(`Transaction: ${tx}`); - vaaIds.forEach((vaaId) => console.log(`VAA ID: ${vaaId}`)); - } else { - console.log(`No VAA ID found for transaction: ${tx}`); - } - } -}; + See the [Platforms folder of the TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/platforms){target=\_blank} for an up-to-date list of the platforms supported by the Wormhole TypeScript SDK. -testFetchVaaId(); - ``` +### Chain Context - 3. **Run the script** +`ChainContext` (from the `@wormhole-foundation/sdk-definitions` package) provides a unified interface for interacting with connected chains. It: - ```bash - npx tsx test/fetchVaaId.run.ts - ``` +- Holds network, chain, and platform configurations +- Caches RPC and protocol clients +- Exposes both platform-inherited and chain-specific methods +- Defines the core types used across the SDK: `Network`, `Chain`, and `Platform` - If successful, the output will be: +```ts +// Get the chain context for the source and destination chains +// This is useful to grab direct clients for the protocols +const srcChain = wh.getChain(senderAddress.chain); +const dstChain = wh.getChain(receiverAddress.chain); -
-npx tsx test/fetchVaaId.run.ts - -Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 -VAA ID: 2/0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585/164170 - -
+const tb = await srcChain.getTokenBridge(); // => TokenBridge<'Evm'> +srcChain.getRpcClient(); // => RpcClient<'Evm'> +``` - If no VAA ID is found, the script will log an error message. +### Addresses -### Fetch the Full VAA +The SDK uses the `UniversalAddress` class to implement the `Address` interface, standardizing address handling across chains. All addresses are parsed into a 32-byte format. Each platform also defines a `NativeAddress` type that understands its native format. These abstractions ensure consistent cross-chain address handling. -Now that you have the VAA ID, we can use it to fetch the full VAA payload from the Wormholescan API. This payload contains the VAA bytes, which will later be used for signature validation. +```ts +// It's possible to convert a string address to its Native address +const ethAddr: NativeAddress<'Evm'> = toNative('Ethereum', '0xbeef...'); -Open `src/helpers/vaaHelper.ts` and create the `fetchVaa()` function to iterate through VAA IDs and extract the `vaaBytes` payload. +// A common type in the SDK is the `ChainAddress` which provides +// the additional context of the `Chain` this address is relevant for +const senderAddress: ChainAddress = Wormhole.chainAddress( + 'Ethereum', + '0xbeef...' +); +const receiverAddress: ChainAddress = Wormhole.chainAddress( + 'Solana', + 'Sol1111...' +); -```typescript title="src/helpers/vaaHelper.ts" -vaaIds: string[] -): Promise<{ id: string; vaaBytes: string }[]> { - const results: { id: string; vaaBytes: string }[] = []; +// Convert the ChainAddress back to its canonical string address format +const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' - for (const id of vaaIds) { - try { - const response = await axios.get(`${WORMHOLESCAN_API}/signed_vaa/${id}`); - const vaaBytes = response.data.vaaBytes; - results.push({ id, vaaBytes }); - } catch (error) { - console.error(`Error fetching VAA for ${id}:`, error); - } - } - return results; +// Or if the ethAddr above is for an emitter and you need the UniversalAddress +const emitterAddr = ethAddr.toUniversalAddress().toString(); +``` + +### Tokens + +The `TokenId` type identifies any token by its chain and address. For standardized tokens, Wormhole uses the token's contract address. For native currencies (e.g., ETH on Ethereum), it uses the keyword `native`. This ensures consistent handling of all tokens. + +```ts +// Get the TokenId for an ERC-20 token +const sourceToken: TokenId = Wormhole.tokenId('Ethereum', '0xbeef...'); +// Get the TokenId for native ETH +const gasToken: TokenId = Wormhole.tokenId('Ethereum', 'native'); +// Convert a TokenId back to a string +const strAddress = Wormhole.canonicalAddress(senderAddress); // => '0xbeef...' +``` + +### Signers + +The SDK's `Signer` interface can be implemented as either a `SignOnlySigner` or a `SignAndSendSigner`, created by wrapping an offline or web wallet: + +- **`SignOnlySigner`**: Signs and serializes unsigned transactions without broadcasting them. Transactions can be inspected or modified before signing. Serialization is chain-specific. See testing signers (e.g., [EVM](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/evm/src/signer.ts){target=\_blank}, [Solana](https://github.com/wormhole-foundation/connect-sdk/blob/main/platforms/solana/src/signer.ts){target=\_blank}) for implementation examples. +- **`SignAndSendSigner`**: Signs and broadcasts transactions, returning their transaction IDs in order. + +```ts +export type Signer = SignOnlySigner | SignAndSendSigner; + +export interface SignOnlySigner { + chain(): ChainName; + address(): string; + // Accept an array of unsigned transactions and return + // an array of signed and serialized transactions. + // The transactions may be inspected or altered before + // signing. + sign(tx: UnsignedTransaction[]): Promise; } + +export interface SignAndSendSigner { + chain(): ChainName; + address(): string; + // Accept an array of unsigned transactions and return + // an array of transaction ids in the same order as the + // unsignedTransactions array. + signAndSend(tx: UnsignedTransaction[]): Promise; +} ``` -???- code "Try it out: VAA retrieval" - If you want to try the function before moving forward, create a script inside the `test` directory +#### Set Up a Signer with Ethers.js - 1. **Create the script file** +To sign transactions programmatically with the Wormhole SDK, you can use [Ethers.js](https://docs.ethers.org/){target=\_blank} to manage private keys and handle signing. Here's an example of setting up a signer using Ethers.js: - ```bash - touch test/fetchVaa.run.ts - ``` +```javascript +import { ethers } from 'ethers'; - 2. **Add the function call** +// Update the following variables +const rpcUrl = 'INSERT_RPC_URL'; +const privateKey = 'INSERT_PRIVATE_KEY'; +const toAddress = 'INSERT_RECIPIENT_ADDRESS'; - ```typescript title="test/fetchVaa.run.ts" - import { fetchVaaId, fetchVaa } from '../src/helpers/vaaHelper'; -import { TXS } from '../src/config/constants'; +// Set up a provider and signer +const provider = new ethers.JsonRpcProvider(rpcUrl); +const signer = new ethers.Wallet(privateKey, provider); -const testFetchVaa = async () => { - for (const tx of TXS) { - const vaaIds = await fetchVaaId([tx]); +// Example: Signing and sending a transaction +async function sendTransaction() { + const tx = { + to: toAddress, + value: ethers.parseUnits('0.1'), // Sending 0.1 ETH + gasPrice: await provider.getGasPrice(), + gasLimit: ethers.toBeHex(21000), + }; - if (vaaIds.length === 0) { - console.log(`No VAA ID found for transaction: ${tx}`); - continue; - } + const transaction = await signer.sendTransaction(tx); + console.log('Transaction hash:', transaction.hash); +} +sendTransaction(); +``` - for (const vaaId of vaaIds) { - const vaaBytes = await fetchVaa([vaaId]); +These components work together to create, sign, and submit a transaction to the blockchain: - console.log( - `Transaction: ${tx}\nVAA ID: ${vaaId}\nVAA Bytes: ${ - vaaBytes.length > 0 ? vaaBytes[0].vaaBytes : 'Not found' - }` - ); - } - } -}; +- **`provider`**: Connects to the Ethereum or EVM-compatible network, enabling data access and transaction submission. +- **`signer`** : Represents the account that signs transactions using a private key. +- **`Wallet`**: Combines provider and signer to create, sign, and send transactions programmatically. -testFetchVaa(); - ``` +### Protocols + +Wormhole is a Generic Message Passing (GMP) protocol with several specialized protocols built on top. Each protocol has platform-specific implementations providing methods to generate transactions or read on-chain state. + +??? interface "Supported protocol modules" + + | Protocol | Installation Command | + |-----------------------|----------------------------------------------------------------| + | EVM Core |
```@wormhole-foundation/sdk-evm-core```
| + | EVM Token Bridge |
```@wormhole-foundation/sdk-evm-tokenbridge```
| + | EVM CCTP |
```@wormhole-foundation/sdk-evm-cctp```
| + | EVM Portico |
```@wormhole-foundation/sdk-evm-portico```
| + | EVM TBTC |
```@wormhole-foundation/sdk-evm-tbtc```
| + | Solana Core |
```@wormhole-foundation/sdk-solana-core```
| + | Solana Token Bridge |
```@wormhole-foundation/sdk-solana-tokenbridge```
| + | Solana CCTP |
```@wormhole-foundation/sdk-solana-cctp```
| + | Solana TBTC |
```@wormhole-foundation/sdk-solana-tbtc```
| + | Algorand Core |
```@wormhole-foundation/sdk-algorand-core```
| + | Algorand Token Bridge |
```@wormhole-foundation/sdk-algorand-tokenbridge```
| + | Aptos Core |
```@wormhole-foundation/sdk-aptos-core```
| + | Aptos Token Bridge |
```@wormhole-foundation/sdk-aptos-tokenbridge```
| + | Aptos CCTP |
```@wormhole-foundation/sdk-aptos-cctp```
| + | Cosmos Core |
```@wormhole-foundation/sdk-cosmwasm-core```
| + | Cosmos Token Bridge |
```@wormhole-foundation/sdk-cosmwasm-tokenbridge```
| + | Sui Core |
```@wormhole-foundation/sdk-sui-core```
| + | Sui Token Bridge |
```@wormhole-foundation/sdk-sui-tokenbridge```
| + | Sui CCTP |
```@wormhole-foundation/sdk-sui-cctp```
| + + +#### Wormhole Core + +The core protocol powers all Wormhole activity by emitting messages containing the [emitter address](/docs/products/reference/glossary/#emitter){target=\_blank}, sequence number, and payload needed for bridging. + +Example workflow on Solana Testnet: + +1. Initialize a Wormhole instance for Solana. +2. Obtain a signer and its address. +3. Access the core messaging bridge for cross-chain messaging. +4. Prepare a message with: - 3. **Run the script** + - Sender's address + - Encoded payload (e.g., "lol") + - Nonce (e.g., 0) + - Consistency level (e.g., 0) - ```bash - npx tsx test/fetchVaa.run.ts - ``` +5. Generate, sign, and send the transaction to publish the message. +6. Extract the Wormhole message ID from transaction logs for tracking. +7. Wait (up to 60s) to receive the [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} (in `Uint8Array` format) from the Wormhole network. +8. Prepare and send a verification transaction on the receiving chain using the sender's address and the VAA. - If successful, the output will be: +???+ example "Example workflow" + ```ts + import { encoding, signSendWait, wormhole } from '@wormhole-foundation/sdk'; +import { getSigner } from './helpers/index.js'; +import solana from '@wormhole-foundation/sdk/solana'; +import evm from '@wormhole-foundation/sdk/evm'; -
-npx tsx test/fetchVaa.run.ts - -Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 -VAA Bytes: AQAAAAMNANQSwD/HRPcKp7Yxypl1ON8dZeMBzgYJrd2KYz6l9Tq9K9fj72fYJgkMeMaB9h... - -
+(async function () { + const wh = await wormhole('Testnet', [solana, evm]); - If no VAA is found, the script will log an error message. + const chain = wh.getChain('Avalanche'); + const { signer, address } = await getSigner(chain); -### Validate VAA Signatures + // Get a reference to the core messaging bridge + const coreBridge = await chain.getWormholeCore(); -Now, we need to verify its validity. A VAA is only considered valid if it contains signatures from currently active Guardians and is correctly verified by the Wormhole Core contract. + // Generate transactions, sign and send them + const publishTxs = coreBridge.publishMessage( + // Address of sender (emitter in VAA) + address.address, + // Message to send (payload in VAA) + encoding.bytes.encode('lol'), + // Nonce (user defined, no requirement for a specific value, useful to provide a unique identifier for the message) + 0, + // ConsistencyLevel (ie finality of the message, see wormhole docs for more) + 0 + ); + // Send the transaction(s) to publish the message + const txids = await signSendWait(chain, publishTxs, signer); -Open `src/helpers/vaaHelper.ts` and add the `checkVaaValidity()` function. This function verifies whether a VAA is valid by submitting it to an Ethereum RPC node and checking for outdated signatures. + // Take the last txid in case multiple were sent + // The last one should be the one containing the relevant + // event or log info + const txid = txids[txids.length - 1]; -Follow these steps to implement the function: + // Grab the wormhole message id from the transaction logs or storage + const [whm] = await chain.parseTransaction(txid!.txid); -1. **Prepare the VAA for verification** - construct the VAA payload in a format that can be sent to the Wormhole Core contract + // Wait for the vaa to be signed and available with a timeout + const vaa = await wh.getVaa(whm!, 'Uint8Array', 60_000); + console.log(vaa); -2. **Send an `eth_call` request** - submit the VAA to an Ethereum RPC node, calling the `parseAndVerifyVM` function on the Wormhole Core contract + // Note: calling verifyMessage manually is typically not a useful thing to do + // As the VAA is typically submitted to the counterpart contract for + // A given protocol and the counterpart contract will verify the VAA + // This is simply for demo purposes + const verifyTxs = coreBridge.verifyMessage(address.address, vaa!); + console.log(await signSendWait(chain, verifyTxs, signer)); +})(); + ``` -3. **Decode the response** - check whether the VAA is valid. If it contains outdated signatures, further action will be required to replace them +The payload contains the information necessary to perform whatever action is required based on the protocol that uses it. -```typescript title="src/helpers/vaaHelper.ts" -try { - const vaa = Buffer.from(vaaBytes, 'base64'); - vaa[4] = 4; // Set guardian set index to 4 +#### Token Bridge - const result = ( - await axios.post(RPC, { - jsonrpc: '2.0', - id: 1, - method: 'eth_call', - params: [ - { - from: null, - to: ETH_CORE, - data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [ - `0x${vaa.toString('hex')}`, - ]), - }, - 'latest', - ], - }) - ).data.result; +The most familiar protocol built on Wormhole is the Token Bridge. Each supported chain has a `TokenBridge` client that provides a consistent interface for transferring tokens and handling attestations. While `WormholeTransfer` abstractions are recommended, direct interaction with the protocol is also supported. - const decoded = eth.abi.decodeParameters( - PARSE_AND_VERIFY_VM_ABI.outputs, - result - ); - console.log( - `${decoded.valid ? '✅' : '❌'} VAA Valid: ${decoded.valid}${ - decoded.valid ? '' : `, Reason: ${decoded.reason}` - }` - ); +```ts +import { signSendWait } from '@wormhole-foundation/sdk'; - return { valid: decoded.valid, reason: decoded.reason }; - } catch (error) { - console.error(`Error checking VAA validity:`, error); - return { valid: false, reason: 'RPC error' }; - } -} +const tb = await srcChain.getTokenBridge(); + +const token = '0xdeadbeef...'; +const txGenerator = tb.createAttestation(token); +const txids = await signSendWait(srcChain, txGenerator, src.signer); ``` -???- code "Try it out: VAA Validity" - If you want to try the function before moving forward, create a script inside the `test` directory +## Transfers - 1. **Create the script file** +While using the [`ChainContext`](#chain-context) and [`Protocol`](#protocols) clients directly is possible, the SDK provides some helpful abstractions for transferring tokens. - ```bash - touch test/checkVaaValidity.run.ts - ``` +The `WormholeTransfer` interface provides a convenient abstraction to encapsulate the steps involved in a cross-chain transfer. - 2. **Add the function call** +### Token Transfers - ```typescript title="test/checkVaaValidity.run.ts" - import { - fetchVaaId, - fetchVaa, - checkVaaValidity, -} from '../src/helpers/vaaHelper'; -import { TXS } from '../src/config/constants'; +Token transfers between chains are straightforward using Wormhole. Create a `Wormhole` instance and use it to initialize a `TokenTransfer` or `CircleTransfer` object. -const testCheckVaaValidity = async () => { - for (const tx of TXS) { - const vaaIds = await fetchVaaId([tx]); +The example below shows how to initiate and complete a `TokenTransfer`. After creating the transfer object and retrieving a quote (to verify sufficient amount and fees), the process involves: - if (vaaIds.length === 0) { - console.log(`No VAA ID found for transaction: ${tx}`); - continue; - } +1. Initiating the transfer on the source chain. +2. Waiting for attestation (if required). +3. Completing the transfer on the destination chain. - for (const vaaId of vaaIds) { - const vaaData = await fetchVaa([vaaId]); +For automatic transfers, the process ends after initiation. Manual transfers require attestation before completion. - if (vaaData.length === 0 || !vaaData[0].vaaBytes) { - console.log(`VAA not found for ID: ${vaaId}`); - continue; - } +```ts +const xfer = await wh.tokenTransfer( + route.token, + route.amount, + route.source.address, + route.destination.address, + route.delivery?.automatic ?? false, + route.payload, + route.delivery?.nativeGas + ); - const result = await checkVaaValidity(vaaData[0].vaaBytes); - console.log( - `Transaction: ${tx}\nVAA ID: ${vaaId}\nVAA Validity:`, - result - ); - } - } -}; + const quote = await TokenTransfer.quoteTransfer( + wh, + route.source.chain, + route.destination.chain, + xfer.transfer + ); + console.log(quote); -testCheckVaaValidity(); - ``` + if (xfer.transfer.automatic && quote.destinationToken.amount < 0) + throw 'The amount requested is too low to cover the fee and any native gas requested.'; - 3. **Run the script** + // 1) Submit the transactions to the source chain, passing a signer to sign any txns + console.log('Starting transfer'); + const srcTxids = await xfer.initiateTransfer(route.source.signer); + console.log(`Started transfer: `, srcTxids); - ```bash - npx tsx test/checkVaaValidity.run.ts - ``` + // If automatic, we're done + if (route.delivery?.automatic) return xfer; - If the VAA is valid, the output will be: + // 2) Wait for the VAA to be signed and ready (not required for auto transfer) + console.log('Getting Attestation'); + const attestIds = await xfer.fetchAttestation(60_000); + console.log(`Got Attestation: `, attestIds); -
-npx tsx test/checkVaaValidity.run.ts - -✅ VAA Valid: true - -
+ // 3) Redeem the VAA on the dest chain + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(route.destination.signer); + console.log(`Completed Transfer: `, destTxids); +``` - If invalid, the output will include the reason: +??? code "View the complete script" + ```ts hl_lines="122" + import { + Chain, + Network, + TokenId, + TokenTransfer, + Wormhole, + amount, + isTokenId, + wormhole, +} from '@wormhole-foundation/sdk'; -
-npx tsx test/checkVaaValidity.run.ts - -❌ VAA Valid: false, Reason: VM signature invalid -Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 - -
+import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { SignerStuff, getSigner, waitLog } from './helpers/index.js'; -### Fetch Observations (VAA Signatures) +(async function () { + // Init Wormhole object, passing config for which network + // to use (e.g. Mainnet/Testnet) and what Platforms to support + const wh = await wormhole('Testnet', [evm, solana]); -Before replacing outdated signatures, we need to fetch the original VAA signatures from Wormholescan. This allows us to compare them with the latest Guardian set and determine which ones need updating. + // Grab chain Contexts -- these hold a reference to a cached rpc client + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Solana'); -Inside `src/helpers/vaaHelper.ts`, create the `fetchObservations()` function to query the Wormholescan API for observations related to a given VAA. Format the response by converting Guardian addresses to lowercase for consistency, and return an empty array if an error occurs. + // Shortcut to allow transferring native gas token + const token = Wormhole.tokenId(sendChain.chain, 'native'); + + // A TokenId is just a `{chain, address}` pair and an alias for ChainAddress + // The `address` field must be a parsed address. + // You can get a TokenId (or ChainAddress) prepared for you + // by calling the static `chainAddress` method on the Wormhole class. + // e.g. + // wAvax on Solana + // const token = Wormhole.tokenId("Solana", "3Ftc5hTz9sG4huk79onufGiebJNDMZNL8HYgdMJ9E7JR"); + // wSol on Avax + // const token = Wormhole.tokenId("Avalanche", "0xb10563644a6AB8948ee6d7f5b0a1fb15AaEa1E03"); + + // Normalized given token decimals later but can just pass bigints as base units + // Note: The Token bridge will dedust past 8 decimals + // This means any amount specified past that point will be returned + // To the caller + const amt = '0.05'; + + // With automatic set to true, perform an automatic transfer. This will invoke a relayer + // Contract intermediary that knows to pick up the transfers + // With automatic set to false, perform a manual transfer from source to destination + // Of the token + // On the destination side, a wrapped version of the token will be minted + // To the address specified in the transfer VAA + const automatic = false; + + // The Wormhole relayer has the ability to deliver some native gas funds to the destination account + // The amount specified for native gas will be swapped for the native gas token according + // To the swap rate provided by the contract, denominated in native gas tokens + const nativeGas = automatic ? '0.01' : undefined; -```typescript title="src/helpers/vaaHelper.ts" -try { - console.log(`Fetching observations`); + // Get signer from local key but anything that implements + // Signer interface (e.g. wrapper around web wallet) should work + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); - const response = await axios.get( - `https://api.wormholescan.io/api/v1/observations/${vaaId}` - ); + // Used to normalize the amount to account for the tokens decimals + const decimals = isTokenId(token) + ? Number(await wh.getDecimals(token.chain, token.address)) + : sendChain.config.nativeTokenDecimals; - return response.data.map((obs: any) => ({ - guardianAddr: obs.guardianAddr.toLowerCase(), - signature: obs.signature, - })); - } catch (error) { - console.error(`Error fetching observations:`, error); - return []; - } -} -``` + // Set this to true if you want to perform a round trip transfer + const roundTrip: boolean = false; -???- code "Try it out: Fetch Observations" - If you want to try the function before moving forward, create a script inside the `test` directory + // Set this to the transfer txid of the initiating transaction to recover a token transfer + // And attempt to fetch details about its progress. + let recoverTxid = undefined; - 1. **Create the script file** + // Finally create and perform the transfer given the parameters set above + const xfer = !recoverTxid + ? // Perform the token transfer + await tokenTransfer( + wh, + { + token, + amount: amount.units(amount.parse(amt, decimals)), + source, + destination, + delivery: { + automatic, + nativeGas: nativeGas + ? amount.units(amount.parse(nativeGas, decimals)) + : undefined, + }, + }, + roundTrip + ) + : // Recover the transfer from the originating txid + await TokenTransfer.from(wh, { + chain: source.chain.chain, + txid: recoverTxid, + }); - ```bash - touch test/fetchObservations.run.ts - ``` + const receipt = await waitLog(wh, xfer); - 2. **Add the function call** + // Log out the results + console.log(receipt); +})(); - ```typescript title="test/fetchObservations.run.ts" - import { fetchVaaId, fetchObservations } from '../src/helpers/vaaHelper'; -import { TXS } from '../src/config/constants'; +async function tokenTransfer( + wh: Wormhole, + route: { + token: TokenId; + amount: bigint; + source: SignerStuff; + destination: SignerStuff; + delivery?: { + automatic: boolean; + nativeGas?: bigint; + }; + payload?: Uint8Array; + }, + roundTrip?: boolean +): Promise> { + // Create a TokenTransfer object to track the state of the transfer over time + const xfer = await wh.tokenTransfer( + route.token, + route.amount, + route.source.address, + route.destination.address, + route.delivery?.automatic ?? false, + route.payload, + route.delivery?.nativeGas + ); -const testFetchObservations = async () => { - for (const tx of TXS) { - const vaaIds = await fetchVaaId([tx]); + const quote = await TokenTransfer.quoteTransfer( + wh, + route.source.chain, + route.destination.chain, + xfer.transfer + ); + console.log(quote); - if (vaaIds.length === 0) { - console.log(`No VAA ID found for transaction: ${tx}`); - continue; - } + if (xfer.transfer.automatic && quote.destinationToken.amount < 0) + throw 'The amount requested is too low to cover the fee and any native gas requested.'; - for (const vaaId of vaaIds) { - const observations = await fetchObservations(vaaId); + // 1) Submit the transactions to the source chain, passing a signer to sign any txns + console.log('Starting transfer'); + const srcTxids = await xfer.initiateTransfer(route.source.signer); + console.log(`Started transfer: `, srcTxids); - if (observations.length === 0) { - console.log(`No observations found for VAA ID: ${vaaId}`); - continue; - } + // If automatic, we're done + if (route.delivery?.automatic) return xfer; - console.log( - `Transaction: ${tx}\nVAA ID: ${vaaId}\nObservations:`, - observations - ); - } - } -}; + // 2) Wait for the VAA to be signed and ready (not required for auto transfer) + console.log('Getting Attestation'); + const attestIds = await xfer.fetchAttestation(60_000); + console.log(`Got Attestation: `, attestIds); -testFetchObservations(); - ``` + // 3) Redeem the VAA on the dest chain + console.log('Completing Transfer'); + const destTxids = await xfer.completeTransfer(route.destination.signer); + console.log(`Completed Transfer: `, destTxids); - 3. **Run the script** + // If no need to send back, dip + if (!roundTrip) return xfer; - ```bash - npx tsx test/fetchObservations.run.ts - ``` + const { destinationToken: token } = quote; + return await tokenTransfer(wh, { + ...route, + token: token.token, + amount: token.amount, + source: route.destination, + destination: route.source, + }); +} + + ``` - If successful, the output will be: +Internally, this uses the [`TokenBridge`](#token-bridge) protocol client to transfer tokens. -
-npx tsx test/fetchObservations.run.ts - -Fetching observations -Transaction: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 -Observations: [ { guardianAddr: '0xda798f6896a3331f64b48c12d1d57fd9cbe70811', signature: - 'ZGFlMDYyOGNjZjFjMmE0ZTk5YzE2OThhZjAzMDM4NzZlYTM1OWMxMzczNDA3YzdlMDMxZTkyNzk0ODkwYjRiYjRiOWFmNzM3NjRiMzIyOTE0ZTQwYzNlMjllMWEzNmM2NTc3ZDc5ZTdhNTM2MzA5YjA4YjExZjE3YzE3MDViNWIwMQ==' - }, { guardianAddr: '0x74a3bf913953d695260d88bc1aa25a4eee363ef0', signature: - 'MzAyOTU4OGU4MWU0ODc0OTAwNDU3N2EzMGZlM2UxMDJjOWYwMjM0NWVhY2VmZWQ0ZGJlNTFkNmI3YzRhZmQ5ZTNiODFjNTg3MDNmYzUzNmJiYWFiZjNlODc1YTY3OTQwMGE4MmE3ZjZhNGYzOGY3YmRmNDNhM2VhNGQyNWNlNGMwMA==' - }, -...] - -
+### Native USDC Transfers - If no observations are found, the script will log an error message. +You can transfer native USDC using [Circle's CCTP](https://www.circle.com/en/cross-chain-transfer-protocol){target=\_blank}. If the transfer is set to `automatic`, the quote will include a relay fee, which is deducted from the total amount sent. For example, to receive 1.0 USDC on the destination chain, the sender must cover both the 1.0 and the relay fee. The same applies when including a native gas drop-off. -### Fetch the Latest Guardian Set +In the example below, the `wh.circleTransfer` function is used to initiate the transfer. It accepts the amount (in base units), sender and receiver chains and addresses, and an optional automatic flag to enable hands-free completion. You can also include an optional payload (set to `undefined` here) and specify a native gas drop-off if desired. -Now that we have the original VAA signatures, we must fetch the latest Guardian set from Wormholescan. This will allow us to compare the stored signatures with the current Guardians and determine which signatures need replacing. +When waiting for the VAA, a timeout of `60,000` milliseconds is used. The actual wait time [varies by network](https://developers.circle.com/stablecoins/docs/required-block-confirmations#mainnet){target=\_blank}. -Create the `fetchGuardianSet()` function inside `src/helpers/vaaHelper.ts` to fetch the latest Guardian set. +```ts +// Amount as bigint (base units) + req.amount, + // Sender chain/address + src.address, + // Receiver chain/address + dst.address, + // Automatic delivery boolean + req.automatic, + // Payload to be sent with the transfer + undefined, + // If automatic, native gas can be requested to be sent to the receiver + req.nativeGas + ); -```typescript title="src/helpers/vaaHelper.ts" -export async function fetchGuardianSet() { - try { - console.log('Fetching current guardian set'); + // Note, if the transfer is requested to be Automatic, a fee for performing the relay + // will be present in the quote. The fee comes out of the amount requested to be sent. + // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. + // The same applies for native gas dropoff + const quote = await CircleTransfer.quoteTransfer( + src.chain, + dst.chain, + xfer.transfer + ); + console.log('Quote', quote); - const response = await axios.get(`${WORMHOLESCAN_API}/guardianset/current`); - const guardians = response.data.guardianSet.addresses.map((addr: string) => - addr.toLowerCase() - ); - const guardianSet = response.data.guardianSet.index; + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(src.signer); + console.log(`Started Transfer: `, srcTxids); - return [guardians, guardianSet]; - } catch (error) { - console.error('Error fetching guardian set:', error); - return []; + if (req.automatic) { + const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); + console.log(`Finished relay: `, relayStatus); + return; } -} -``` - -???- code "Try it out: Fetch Guardian Set" - If you want to try the function before moving forward, create a script inside the `test` directory - 1. **Create the script file** + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(60_000); + console.log(`Got Attestation: `, attestIds); - ```bash - touch test/fetchGuardianSet.run.ts - ``` + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(dst.signer); + console.log(`Completed Transfer: `, dstTxids); +} +``` - 2. **Add the function call** +??? code "View the complete script" + ```ts + import { + Chain, + CircleTransfer, + Network, + Signer, + TransactionId, + TransferState, + Wormhole, + amount, + wormhole, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { SignerStuff, getSigner, waitForRelay } from './helpers/index.js'; - ```typescript title="test/fetchGuardianSet.run.ts" - import { fetchGuardianSet } from '../src/helpers/vaaHelper'; +/* +Notes: +Only a subset of chains are supported by Circle for CCTP, see core/base/src/constants/circle.ts for currently supported chains -const testFetchGuardianSet = async () => { - const [guardians, guardianSetIndex] = await fetchGuardianSet(); +AutoRelayer takes a 0.1 USDC fee when transferring to any chain beside Goerli, which is 1 USDC +*/ +// - console.log('Current Guardian Set Index:', guardianSetIndex); - console.log('Guardian Addresses:', guardians); -}; +(async function () { + // Init the Wormhole object, passing in the config for which network + // to use (e.g. Mainnet/Testnet) and what Platforms to support + const wh = await wormhole('Testnet', [evm, solana]); -testFetchGuardianSet(); - ``` + // Grab chain Contexts + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Solana'); - 3. **Run the script** + // Get signer from local key but anything that implements + // Signer interface (e.g. wrapper around web wallet) should work + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); - ```bash - npx tsx test/fetchGuardianSet.run.ts - ``` + // 6 decimals for USDC (except for BSC, so check decimals before using this) + const amt = amount.units(amount.parse('0.2', 6)); - If successful, the output will be: + // Choose whether or not to have the attestation delivered for you + const automatic = false; -
-npx tsx test/fetchGuardianSet.run.ts - -Fetching current guardian set -Current Guardian Set Index: 4 -Guardian Addresses: [ - '0x5893b5a76c3f739645648885bdccc06cd70a3cd3', - '0xff6cb952589bde862c25ef4392132fb9d4a42157', - '0x114de8460193bdf3a2fcf81f86a09765f4762fd1', - '0x107a0086b32d7a0977926a205131d8731d39cbeb', - -...] - -
+ // If the transfer is requested to be automatic, you can also request that + // during redemption, the receiver gets some amount of native gas transferred to them + // so that they may pay for subsequent transactions + // The amount specified here is denominated in the token being transferred (USDC here) + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; - If an error occurs while fetching the Guardian set, a `500` status error will be logged. + await cctpTransfer(wh, source, destination, { + amount: amt, + automatic, + nativeGas, + }); -### Replace Outdated Signatures +})(); -With the full VAA, Guardian signatures, and the latest Guardian set, we can now update outdated signatures while maintaining the required signature count. +async function cctpTransfer( + wh: Wormhole, + src: SignerStuff, + dst: SignerStuff, + req: { + amount: bigint; + automatic: boolean; + nativeGas?: bigint; + } +) { -1. **Create the `replaceSignatures()` function** - open `src/helpers/vaaHelper.ts` and add the function header. To catch and handle errors properly, all logic will be wrapped inside a `try` block + const xfer = await wh.circleTransfer( + // Amount as bigint (base units) + req.amount, + // Sender chain/address + src.address, + // Receiver chain/address + dst.address, + // Automatic delivery boolean + req.automatic, + // Payload to be sent with the transfer + undefined, + // If automatic, native gas can be requested to be sent to the receiver + req.nativeGas + ); - ```typescript title="src/helpers/vaaHelper.ts" - vaa: string | Uint8Array, - observations: { guardianAddr: string; signature: string }[], - currentGuardians: string[], - guardianSetIndex: number -) { - console.log('Replacing Signatures...'); + // Note, if the transfer is requested to be Automatic, a fee for performing the relay + // will be present in the quote. The fee comes out of the amount requested to be sent. + // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. + // The same applies for native gas dropoff + const quote = await CircleTransfer.quoteTransfer( + src.chain, + dst.chain, + xfer.transfer + ); + console.log('Quote', quote); - try { - // Add logic in the following steps here - console.error('Unexpected error in replaceSignatures:', error); + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(src.signer); + console.log(`Started Transfer: `, srcTxids); + + if (req.automatic) { + const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); + console.log(`Finished relay: `, relayStatus); + return; } -} - ``` - - **`vaa`** - original VAA bytes - - **`observations`** - observed signatures from the network - - **`currentGuardians`** - latest Guardian set - - **`guardianSetIndex`** - current Guardian set index + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(60_000); + console.log(`Got Attestation: `, attestIds); -2. **Validate input data** - ensure all required parameters are present before proceeding. If any required input is missing, the function throws an error to prevent execution with incomplete data. The Guardian set should never be empty; if it is, this likely indicates an error in fetching the Guardian set in a previous step + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(dst.signer); + console.log(`Completed Transfer: `, dstTxids); +} - ```typescript - if (currentGuardians.length === 0) - throw new Error('Guardian set is empty.'); - if (observations.length === 0) throw new Error('No observations provided.'); - ``` +export async function completeTransfer( + wh: Wormhole, + txid: TransactionId, + signer: Signer +): Promise { -3. **Filter valid signatures** - remove signatures from inactive Guardians, keeping only valid ones. If there aren't enough valid signatures to replace the outdated ones, execution is halted to prevent an incomplete or invalid VAA + const xfer = await CircleTransfer.from(wh, txid); - ```typescript - currentGuardians.includes(sig.guardianAddr) - ); + const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); + console.log('Got attestation: ', attestIds); - if (validSigs.length === 0) - throw new Error('No valid signatures found. Cannot proceed.'); + const dstTxIds = await xfer.completeTransfer(signer); + console.log('Completed transfer: ', dstTxIds); +} + ``` -4. **Convert valid signatures** - ensure signatures are correctly formatted for verification. Convert hex-encoded signatures if necessary and extract their components +### Recovering Transfers - ```typescript - .map((sig) => { - try { - const sigBuffer = Buffer.from(sig.signature, 'base64'); - // If it's 130 bytes, it's hex-encoded and needs conversion - const sigBuffer1 = - sigBuffer.length === 130 - ? Buffer.from(sigBuffer.toString(), 'hex') - : sigBuffer; +It may be necessary to recover an abandoned transfer before it is completed. To do this, instantiate the `Transfer` class with the `from` static method and pass one of several types of identifiers. A `TransactionId` or `WormholeMessageId` may be used to recover the transfer. - const r = BigInt('0x' + sigBuffer1.subarray(0, 32).toString('hex')); - const s = BigInt('0x' + sigBuffer1.subarray(32, 64).toString('hex')); - const vRaw = sigBuffer1[64]; - const v = vRaw < 27 ? vRaw : vRaw - 27; +```ts +const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); + console.log('Got attestation: ', attestIds); - return { - guardianIndex: currentGuardians.indexOf(sig.guardianAddr), - signature: new Signature(r, s, v), - }; - } catch (error) { - console.error( - `Failed to process signature for guardian: ${sig.guardianAddr}`, - error - ); - return null; - } - }) - .filter( - (sig): sig is { guardianIndex: number; signature: Signature } => - sig !== null - ); // Remove null values - ``` + const dstTxIds = await xfer.completeTransfer(signer); + console.log('Completed transfer: ', dstTxIds); +``` -5. **Deserialize the VAA** - convert the raw VAA data into a structured format for further processing +??? code "View the complete script" + ```ts hl_lines="130" + import { + Chain, + CircleTransfer, + Network, + Signer, + TransactionId, + TransferState, + Wormhole, + amount, + wormhole, +} from '@wormhole-foundation/sdk'; +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { SignerStuff, getSigner, waitForRelay } from './helpers/index.js'; - ```typescript - try { - parsedVaa = deserialize('Uint8Array', vaa); - } catch (error) { - throw new Error(`Error deserializing VAA: ${error}`); - } - ``` +/* +Notes: +Only a subset of chains are supported by Circle for CCTP, see core/base/src/constants/circle.ts for currently supported chains -6. **Identify outdated signatures** - compare the current VAA signatures with the newly formatted ones to detect which signatures belong to outdated Guardians. Remove these outdated signatures to ensure only valid ones remain +AutoRelayer takes a 0.1 USDC fee when transferring to any chain beside Goerli, which is 1 USDC +*/ +// - ```typescript - .filter( - (vaaSig) => - !formattedSigs.some( - (sig) => sig.guardianIndex === vaaSig.guardianIndex - ) - ) - .map((sig) => sig.guardianIndex); +(async function () { + // Init the Wormhole object, passing in the config for which network + // to use (e.g. Mainnet/Testnet) and what Platforms to support + const wh = await wormhole('Testnet', [evm, solana]); - console.log('Outdated Guardian Indexes:', outdatedGuardianIndexes); + // Grab chain Contexts + const sendChain = wh.getChain('Avalanche'); + const rcvChain = wh.getChain('Solana'); - let updatedSignatures = parsedVaa.signatures.filter( - (sig) => !outdatedGuardianIndexes.includes(sig.guardianIndex) - ); - ``` + // Get signer from local key but anything that implements + // Signer interface (e.g. wrapper around web wallet) should work + const source = await getSigner(sendChain); + const destination = await getSigner(rcvChain); -7. **Replace outdated signatures** - substitute outdated signatures with valid ones while maintaining the correct number of signatures. If there aren’t enough valid replacements, execution stops + // 6 decimals for USDC (except for BSC, so check decimals before using this) + const amt = amount.units(amount.parse('0.2', 6)); - ```typescript - (sig) => - !updatedSignatures.some((s) => s.guardianIndex === sig.guardianIndex) - ); + // Choose whether or not to have the attestation delivered for you + const automatic = false; + + // If the transfer is requested to be automatic, you can also request that + // during redemption, the receiver gets some amount of native gas transferred to them + // so that they may pay for subsequent transactions + // The amount specified here is denominated in the token being transferred (USDC here) + const nativeGas = automatic ? amount.units(amount.parse('0.0', 6)) : 0n; - // Check if we have enough valid signatures to replace outdated ones** - if (outdatedGuardianIndexes.length > validReplacements.length) { - console.warn( - `Not enough valid replacement signatures! Need ${outdatedGuardianIndexes.length}, but only ${validReplacements.length} available.` - ); - return; - } + await cctpTransfer(wh, source, destination, { + amount: amt, + automatic, + nativeGas, + }); - updatedSignatures = [ - ...updatedSignatures, - ...validReplacements.slice(0, outdatedGuardianIndexes.length), - ]; +})(); - updatedSignatures.sort((a, b) => a.guardianIndex - b.guardianIndex); - ``` +async function cctpTransfer( + wh: Wormhole, + src: SignerStuff, + dst: SignerStuff, + req: { + amount: bigint; + automatic: boolean; + nativeGas?: bigint; + } +) { -8. **Serialize the updated VAA** - reconstruct the VAA with the updated signatures and convert it into a format suitable for submission + const xfer = await wh.circleTransfer( + // Amount as bigint (base units) + req.amount, + // Sender chain/address + src.address, + // Receiver chain/address + dst.address, + // Automatic delivery boolean + req.automatic, + // Payload to be sent with the transfer + undefined, + // If automatic, native gas can be requested to be sent to the receiver + req.nativeGas + ); - ```typescript - ...parsedVaa, - guardianSet: guardianSetIndex, - signatures: updatedSignatures, - }; + // Note, if the transfer is requested to be Automatic, a fee for performing the relay + // will be present in the quote. The fee comes out of the amount requested to be sent. + // If the user wants to receive 1.0 on the destination, the amount to send should be 1.0 + fee. + // The same applies for native gas dropoff + const quote = await CircleTransfer.quoteTransfer( + src.chain, + dst.chain, + xfer.transfer + ); + console.log('Quote', quote); - let patchedVaa: Uint8Array; - try { - patchedVaa = serialize(updatedVaa); - } catch (error) { - throw new Error(`Error serializing updated VAA: ${error}`); - } - ``` + console.log('Starting Transfer'); + const srcTxids = await xfer.initiateTransfer(src.signer); + console.log(`Started Transfer: `, srcTxids); -9. **Send the updated VAA for verification and handle errors** - submit the updated VAA to an Ethereum RPC node for validation, ensuring it can be proposed for Guardian approval. If an error occurs during submission or signature replacement, log the issue and prevent further execution + if (req.automatic) { + const relayStatus = await waitForRelay(srcTxids[srcTxids.length - 1]!); + console.log(`Finished relay: `, relayStatus); + return; + } - ```typescript - if (!(patchedVaa instanceof Uint8Array)) - throw new Error('Patched VAA is not a Uint8Array!'); + console.log('Waiting for Attestation'); + const attestIds = await xfer.fetchAttestation(60_000); + console.log(`Got Attestation: `, attestIds); - const vaaHex = `0x${Buffer.from(patchedVaa).toString('hex')}`; + console.log('Completing Transfer'); + const dstTxids = await xfer.completeTransfer(dst.signer); + console.log(`Completed Transfer: `, dstTxids); +} - console.log('Sending updated VAA to RPC...'); +export async function completeTransfer( + wh: Wormhole, + txid: TransactionId, + signer: Signer +): Promise { - const result = await axios.post(RPC, { - jsonrpc: '2.0', - id: 1, - method: 'eth_call', - params: [ - { - from: null, - to: ETH_CORE, - data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [vaaHex]), - }, - 'latest', - ], - }); + const xfer = await CircleTransfer.from(wh, txid); - const verificationResult = result.data.result; - console.log('Updated VAA (hex):', vaaHex); - return verificationResult; - } catch (error) { - throw new Error(`Error sending updated VAA to RPC: ${error}`); - } - ``` + const attestIds = await xfer.fetchAttestation(60 * 60 * 1000); + console.log('Got attestation: ', attestIds); -???- code "Complete Function" - ```typescript - vaa: string | Uint8Array, - observations: { guardianAddr: string; signature: string }[], - currentGuardians: string[], - guardianSetIndex: number -) { - console.log('Replacing Signatures...'); + const dstTxIds = await xfer.completeTransfer(signer); + console.log('Completed transfer: ', dstTxIds); +} + + ``` - try { - if (!vaa) throw new Error('VAA is undefined or empty.'); - if (currentGuardians.length === 0) - throw new Error('Guardian set is empty.'); - if (observations.length === 0) throw new Error('No observations provided.'); +## Routes - const validSigs = observations.filter((sig) => - currentGuardians.includes(sig.guardianAddr) - ); +While a specific `WormholeTransfer`, such as `TokenTransfer` or `CCTPTransfer`, may be used, the developer must know exactly which transfer type to use for a given request. - if (validSigs.length === 0) - throw new Error('No valid signatures found. Cannot proceed.'); +To provide a more flexible and generic interface, the `Wormhole` class provides a method to produce a `RouteResolver` that can be configured with a set of possible routes to be supported. - const formattedSigs = validSigs - .map((sig) => { - try { - const sigBuffer = Buffer.from(sig.signature, 'base64'); - // If it's 130 bytes, it's hex-encoded and needs conversion - const sigBuffer1 = - sigBuffer.length === 130 - ? Buffer.from(sigBuffer.toString(), 'hex') - : sigBuffer; +The following section demonstrates setting up and validating a token transfer using Wormhole's routing system. - const r = BigInt('0x' + sigBuffer1.subarray(0, 32).toString('hex')); - const s = BigInt('0x' + sigBuffer1.subarray(32, 64).toString('hex')); - const vRaw = sigBuffer1[64]; - const v = vRaw < 27 ? vRaw : vRaw - 27; +```ts +const resolver = wh.resolver([ + routes.TokenBridgeRoute, // manual token bridge + routes.AutomaticTokenBridgeRoute, // automatic token bridge + routes.CCTPRoute, // manual CCTP + routes.AutomaticCCTPRoute, // automatic CCTP + routes.AutomaticPorticoRoute, // Native eth transfers + ]); +``` - return { - guardianIndex: currentGuardians.indexOf(sig.guardianAddr), - signature: new Signature(r, s, v), - }; - } catch (error) { - console.error( - `Failed to process signature for guardian: ${sig.guardianAddr}`, - error - ); - return null; - } - }) - .filter( - (sig): sig is { guardianIndex: number; signature: Signature } => - sig !== null - ); // Remove null values +Once created, the resolver can be used to provide a list of input and possible output tokens. - let parsedVaa: VAA<'Uint8Array'>; - try { - parsedVaa = deserialize('Uint8Array', vaa); - } catch (error) { - throw new Error(`Error deserializing VAA: ${error}`); - } +```ts +const srcTokens = await resolver.supportedSourceTokens(sendChain); + console.log( + 'Allowed source tokens: ', + srcTokens.map((t) => canonicalAddress(t)) + ); - const outdatedGuardianIndexes = parsedVaa.signatures - .filter( - (vaaSig) => - !formattedSigs.some( - (sig) => sig.guardianIndex === vaaSig.guardianIndex - ) - ) - .map((sig) => sig.guardianIndex); + const sendToken = Wormhole.tokenId(sendChain.chain, 'native'); - console.log('Outdated Guardian Indexes:', outdatedGuardianIndexes); + // Given the send token, what can we possibly get on the destination chain? + const destTokens = await resolver.supportedDestinationTokens( + sendToken, + sendChain, + destChain + ); + console.log( + 'For the given source token and routes configured, the following tokens may be receivable: ', + destTokens.map((t) => canonicalAddress(t)) + ); + // Grab the first one for the example + const destinationToken = destTokens[0]!; +``` - let updatedSignatures = parsedVaa.signatures.filter( - (sig) => !outdatedGuardianIndexes.includes(sig.guardianIndex) - ); +Once the tokens are selected, a `RouteTransferRequest` may be created to provide a list of routes that can fulfill the request. Creating a transfer request fetches the token details since all routes will need to know about the tokens. - const validReplacements = formattedSigs.filter( - (sig) => - !updatedSignatures.some((s) => s.guardianIndex === sig.guardianIndex) - ); +```ts +// Since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source: sendToken, + destination: destinationToken, + }); - // Check if we have enough valid signatures to replace outdated ones** - if (outdatedGuardianIndexes.length > validReplacements.length) { - console.warn( - `Not enough valid replacement signatures! Need ${outdatedGuardianIndexes.length}, but only ${validReplacements.length} available.` - ); - return; - } + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + console.log( + 'For the transfer parameters, we found these routes: ', + foundRoutes + ); +``` - updatedSignatures = [ - ...updatedSignatures, - ...validReplacements.slice(0, outdatedGuardianIndexes.length), - ]; +Choosing the best route is up to the developer and may involve sorting by output amount or estimated completion time (though no estimate is currently provided). - updatedSignatures.sort((a, b) => a.guardianIndex - b.guardianIndex); +Once a route is selected, parameters like `amount`, `nativeGasDropoff`, and `slippage` can be set. After validation, a transfer quote is requested, including fees, estimated time, and final amount. If successful, the quote is shown to the user for review before proceeding, ensuring all details are verified prior to transfer. - const updatedVaa: VAA<'Uint8Array'> = { - ...parsedVaa, - guardianSet: guardianSetIndex, - signatures: updatedSignatures, - }; +```ts +'This route offers the following default options', + bestRoute.getDefaultOptions() + ); - let patchedVaa: Uint8Array; - try { - patchedVaa = serialize(updatedVaa); - } catch (error) { - throw new Error(`Error serializing updated VAA: ${error}`); - } + // Specify the amount as a decimal string + const amt = '0.001'; + // Create the transfer params for this request + const transferParams = { amount: amt, options: { nativeGas: 0 } }; - try { - if (!(patchedVaa instanceof Uint8Array)) - throw new Error('Patched VAA is not a Uint8Array!'); + // Validate the transfer params passed, this returns a new type of ValidatedTransferParams + // which (believe it or not) is a validated version of the input params + // This new var must be passed to the next step, quote + const validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) throw validated.error; + console.log('Validated parameters: ', validated.params); - const vaaHex = `0x${Buffer.from(patchedVaa).toString('hex')}`; + // Get a quote for the transfer, this too returns a new type that must + // be passed to the next step, execute (if you like the quote) + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) throw quote.error; + console.log('Best route quote: ', quote); +``` - console.log('Sending updated VAA to RPC...'); +Finally, assuming the quote looks good, the route can initiate the request with the quote and the `signer`. - const result = await axios.post(RPC, { - jsonrpc: '2.0', - id: 1, - method: 'eth_call', - params: [ - { - from: null, - to: ETH_CORE, - data: eth.abi.encodeFunctionCall(PARSE_AND_VERIFY_VM_ABI, [vaaHex]), - }, - 'latest', - ], - }); +```ts +tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); +``` - const verificationResult = result.data.result; - console.log('Updated VAA (hex):', vaaHex); - return verificationResult; - } catch (error) { - throw new Error(`Error sending updated VAA to RPC: ${error}`); - } - } catch (error) { - console.error('Unexpected error in replaceSignatures:', error); - } -} - ``` +??? code "View the complete script" -## Create Script to Replace Outdated VAA Signatures + ```ts + import { + Wormhole, + canonicalAddress, + routes, + wormhole, +} from '@wormhole-foundation/sdk'; -Now that we have all the necessary helper functions, we will create a script to automate replacing outdated VAA signatures. This script will retrieve a transaction’s VAA sequentially, check its validity, fetch the latest Guardian set, and update its signatures. By the end, it will output a correctly signed VAA that can be proposed for Guardian approval. +import evm from '@wormhole-foundation/sdk/evm'; +import solana from '@wormhole-foundation/sdk/solana'; +import { getSigner } from './helpers/index.js'; -1. **Open the file** - inside `src/scripts/replaceSignatures.ts`, import the required helper functions needed to process the VAAs +(async function () { + // Setup + const wh = await wormhole('Testnet', [evm, solana]); - ```typescript title="src/scripts/replaceSignatures.ts" - fetchVaaId, - fetchVaa, - checkVaaValidity, - fetchObservations, - fetchGuardianSet, - replaceSignatures, -} from '../helpers/vaaHelper'; -import { TXS } from '../config/constants'; - ``` + // Get chain contexts + const sendChain = wh.getChain('Avalanche'); + const destChain = wh.getChain('Solana'); -2. **Define the main execution function** - add the following function inside `src/scripts/replaceSignatures.ts` to process each transaction in `TXS`, going step by step through the signature replacement process + // Get signers from local config + const sender = await getSigner(sendChain); + const receiver = await getSigner(destChain); - ```typescript - try { - for (const tx of TXS) { - console.log(`\nProcessing TX: ${tx}\n`); + // Create new resolver, passing the set of routes to consider + const resolver = wh.resolver([ + routes.TokenBridgeRoute, // manual token bridge + routes.AutomaticTokenBridgeRoute, // automatic token bridge + routes.CCTPRoute, // manual CCTP + routes.AutomaticCCTPRoute, // automatic CCTP + routes.AutomaticPorticoRoute, // Native eth transfers + ]); - // 1. Fetch Transaction VAA IDs: - const vaaIds = await fetchVaaId([tx]); - if (!vaaIds.length) continue; + // What tokens are available on the source chain? + const srcTokens = await resolver.supportedSourceTokens(sendChain); + console.log( + 'Allowed source tokens: ', + srcTokens.map((t) => canonicalAddress(t)) + ); - // 2. Fetch VAA Data: - const vaaData = await fetchVaa(vaaIds); - if (!vaaData.length) continue; + const sendToken = Wormhole.tokenId(sendChain.chain, 'native'); - const vaaBytes = vaaData[0].vaaBytes; - if (!vaaBytes) continue; + // Given the send token, what can we possibly get on the destination chain? + const destTokens = await resolver.supportedDestinationTokens( + sendToken, + sendChain, + destChain + ); + console.log( + 'For the given source token and routes configured, the following tokens may be receivable: ', + destTokens.map((t) => canonicalAddress(t)) + ); + // Grab the first one for the example + const destinationToken = destTokens[0]!; - // 3. Check VAA Validity: - const { valid } = await checkVaaValidity(vaaBytes); - if (valid) continue; + // Creating a transfer request fetches token details + // Since all routes will need to know about the tokens + const tr = await routes.RouteTransferRequest.create(wh, { + source: sendToken, + destination: destinationToken, + }); - // 4. Fetch Observations (VAA signatures): - const observations = await fetchObservations(vaaIds[0]); + // Resolve the transfer request to a set of routes that can perform it + const foundRoutes = await resolver.findRoutes(tr); + console.log( + 'For the transfer parameters, we found these routes: ', + foundRoutes + ); - // 5. Fetch Current Guardian Set: - const [currentGuardians, guardianSetIndex] = await fetchGuardianSet(); + const bestRoute = foundRoutes[0]!; + console.log('Selected: ', bestRoute); - // 6. Replace Signatures: - const response = await replaceSignatures( - Buffer.from(vaaBytes, 'base64'), - observations, - currentGuardians, - guardianSetIndex - ); + console.log( + 'This route offers the following default options', + bestRoute.getDefaultOptions() + ); - if (!response) continue; - } - } catch (error) { - console.error('❌ Error in execution:', error); - process.exit(1); - } -} - ``` + // Specify the amount as a decimal string + const amt = '0.001'; + // Create the transfer params for this request + const transferParams = { amount: amt, options: { nativeGas: 0 } }; -3. **Make the script executable** - ensure it runs when executed + // Validate the transfer params passed, this returns a new type of ValidatedTransferParams + // which (believe it or not) is a validated version of the input params + // This new var must be passed to the next step, quote + const validated = await bestRoute.validate(tr, transferParams); + if (!validated.valid) throw validated.error; + console.log('Validated parameters: ', validated.params); - ```typescript - - ``` + // Get a quote for the transfer, this too returns a new type that must + // be passed to the next step, execute (if you like the quote) + const quote = await bestRoute.quote(tr, validated.params); + if (!quote.success) throw quote.error; + console.log('Best route quote: ', quote); - To run the script, use the following command: + // If you're sure you want to do this, set this to true + const imSure = false; + if (imSure) { + // Now the transfer may be initiated + // A receipt will be returned, guess what you gotta do with that? + const receipt = await bestRoute.initiate( + tr, + sender.signer, + quote, + receiver.address + ); + console.log('Initiated transfer with receipt: ', receipt); - ```bash - npx tsx src/scripts/replaceSignatures.ts + // Kick off a wait log, if there is an opportunity to complete, this function will do it + // See the implementation for how this works + await routes.checkAndCompleteTransfer(bestRoute, receipt, receiver.signer); + } else { + console.log('Not initiating transfer (set `imSure` to true to do so)'); + } +})(); ``` -
-npx tsx src/scripts/replaceSignatures.ts - -Processing TX: 0x3ad91ec530187bb2ce3b394d587878cd1e9e037a97e51fbc34af89b2e0719367 -❌ VAA Valid: false, Reason: VM signature invalid -Fetching observations -Fetching current guardian set -Replacing Signatures... -Outdated Guardian Indexes: [ 0 ] -Sending updated VAA to RPC... -Updated VAA (hex): 0x01000000040d010019447b72d51e33923a3d6b28496ccd3722d5f1e33e2... - -
+See the `router.ts` example in the [examples directory](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main/examples){target=\_blank} for a full working example. -The script logs each step, skipping valid VAAs, replacing outdated signatures for invalid VAAs, and logging any errors. It then completes with a valid VAA ready for submission. +### Routes as Plugins -## Resources +Routes can be imported from any npm package that exports them and configured with the resolver. Custom routes must extend [`Route`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L21-L64){target=\_blank} and implement [`StaticRouteMethods`](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/0c57292368146c460abc9ce9e7f6a42be8e0b903/connect/src/routes/route.ts#L101){target=\_blank}. -You can explore the complete project and find all necessary scripts and configurations in Wormhole's [demo GitHub repository](https://github.com/wormhole-foundation/demo-vaa-signature-replacement){target=\_blank}. +```ts +import { Network, routes } from '@wormhole-foundation/sdk-connect'; -The demo repository includes a bonus script to check the VAA redemption status on Ethereum and Solana, allowing you to verify whether a transaction has already been redeemed on the destination chain. +export class CustomRoute + extends routes.Route + implements routes.StaticRouteMethods +{ + static meta = { + name: 'CustomRoute', + }; + // implementation... +} + +``` -## Conclusion +A noteworthy example of a route exported from a separate npm package is Wormhole Native Token Transfers (NTT). See the [`NttAutomaticRoute`](https://github.com/wormhole-foundation/native-token-transfers/blob/66f8e414223a77f5c736541db0a7a85396cab71c/sdk/route/src/automatic.ts#L48){target=\_blank} route implementation. -You've successfully built a script to fetch, validate, and replace outdated signatures in VAAs using Wormholescan and the Wormhole SDK. +## See Also -It's important to note that this tutorial does not update VAAs in the Wormhole network. Before redeeming the VAA, you must propose it for Guardian approval to finalize the process. +The TSdoc is available [on GitHub](https://wormhole-foundation.github.io/wormhole-sdk-ts/){target=\_blank}. --- END CONTENT --- diff --git a/llms.txt b/llms.txt index 262cf90b7..2a643c9d7 100644 --- a/llms.txt +++ b/llms.txt @@ -4,116 +4,96 @@ ## Docs -- [Get Started with Core Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/core-contracts.md): This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts -- [Core Messaging Layer Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/index.md): Learn to use Wormhole’s foundational messaging contracts to build multichain apps with direct control over publishing, verifying, relaying, and more. -- [Wormhole-Deployed Relayers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/core-messaging/wormhole-relayers.md): Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. -- [Build with Wormhole](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/index.md): Learn how to start building multichain solutions on Wormhole, with tips to get started, an overview of the toolkit, and an introduction to the protocols. -- [Run Infrastructure Services](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/index.md): Follow the guides in this section to learn how to run off-chain infrastructure services, such as running a spy or a customized relayer. -- [Relayers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers/index.md): Learn how to develop your own custom off-chain relaying service, giving you greater control and flexibility than using Wormhole-deployed relayers. -- [Run a Relayer](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/relayers/run-relayer.md): Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. -- [Spy](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/spy/index.md): Discover everything you need to about the Wormhole Spy, a daemon that watches the Guardian Network and subscribe to signed messages. -- [Run a Spy](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/infrastructure/spy/run-spy.md): Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. -- [Deploy MultiGov on EVM Chains](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-evm.md): Set up and deploy MultiGov to EVM locally with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. -- [MultiGov Deployment to Solana](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/deploy-to-solana.md): Learn how to deploy the MultiGov Staking Program on Solana, including setup, funding, deployment, and configuration steps. -- [MultiGov Technical FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/faq.md): Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. -- [Getting Started with MultiGov](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/index.md): Learn how to get started with MultiGov, from evaluating cross-chain governance needs to deploying with help from the Tally team. -- [Upgrading MultiGov on EVM](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-evm.md): Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. -- [Upgrading MultiGov on Solana](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/multigov/upgrade-solana.md): Learn the process and key considerations for upgrading MultiGov on Solana, ensuring system integrity and careful planning across cross-chain components. -- [Queries FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/faqs.md): Wormhole Queries FAQ covering available libraries, query examples, response formats, and details about running query proxy servers. -- [Wormhole Queries](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/index.md): Wormhole Queries offers on-demand access to Guardian-attested on-chain data via a simple REST endpoint to initiate an off-chain request via a proxy. -- [Queries Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/overview.md): Explore Wormhole Queries, offering real-time access to verified blockchain data via a REST endpoint, enabling secure cross-chain interactions and verifications. -- [Use Queries](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/queries/use-queries.md): Explore a simple demo of interacting with Wormhole Queries using an eth_call request to query the supply of wETH on Ethereum using a Wormhole query. -- [Chain IDs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/chain-ids.md): This page documents the Wormhole-specific chain IDs for each chain and contrasts them to the more commonly referenced EVM chain IDs originating in EIP-155. -- [Wormhole Finality | Consistency Levels](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/consistency-levels.md): This page documents how long to wait for finality before signing, based on each chain’s consistency (finality) level and consensus mechanism. -- [Contract Addresses](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/contract-addresses.md): This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. -- [Reference](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/index.md): Find essential reference information for development, including canonical contract addresses, Wormhole chain IDs, and Wormhole finality levels for Guardians. -- [Wormhole Formatted Addresses](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/reference/wormhole-formatted-addresses.md): Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. -- [Start Building](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/index.md): This section has all you need to start developing with Wormhole, including a guide to supported networks, tool sets, and code examples. -- [Compare Wormhole's Cross-Chain Solutions](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/products.md): Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. -- [Supported Networks](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/supported-networks.md): Learn about the networks each Wormhole product supports, and explore links to documentation, official websites, and block explorers. -- [Testnet Faucets](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/testnet-faucets.md): This page includes resources to quickly find the Testnet tokens you need to deploy and test applications and contracts on Wormhole's supported networks. -- [Use Cases](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/start-building/use-cases.md): Explore Wormhole's use cases, from cross-chain swaps to DeFi, lending, gaming, and more. See how projects integrate Wormhole solutions. -- [Wormhole CLI](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/cli.md): Learn how to install and use the Wormhole CLI, including commands and examples for managing multichain deployments, generating VAAs, and querying contract info. -- [Local Dev Environment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/dev-env.md): Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more. -- [Toolkit FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/faqs.md): FAQs on Wormhole Toolkit, covering Wormholescan, CLI, SDKs (TypeScript, Solidity), Tilt, error handling, transaction history, and manual VAA submission. -- [Wormhole Tooling](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/index.md): This page lists key dev tools, including the WormholeScan Explorer, Wormhole CLI, Wormhole SDKs, and APIs for querying network data. -- [Solidity SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/solidity-sdk.md): How to use the Wormhole Solidity SDK for cross-chain messaging, token transfers, and integrating decentralized applications on EVM-compatible blockchains. -- [Wormhole SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/index.md): The Wormhole SDK provides tools for cross-chain communication, token bridges, and more, enabling developers to integrate with multiple blockchain environments. -- [Building Protocols and Payloads](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/protocols-payloads.md): Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. -- [Data Layouts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/sdk-layout.md): Learn how to efficiently define, serialize, and deserialize data structures using Wormhole SDK's layout system for cross-chain communication. -- [VAAs and Protocols](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/vaas-protocols.md): Understand how VAAs enable cross-chain messaging and how to handle them using Wormhole's TypeScript and Solidity SDKs. -- [Wormhole TS SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/toolkit/typescript-sdk/wormhole-sdk.md): Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC. -- [Interacting with CCTP Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/cctp.md): Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. -- [Configure Your Connect Widget v0](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration-v0.md): Configure Wormhole Connect v0 for React or HTML, set themes, define tokens, networks, and customize RPC endpoints for optimized blockchain interactions. -- [Connect Data Configuration](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-data.md): Configure Wormhole Connect v1 (latest) with custom chains, tokens, routes, and more for enhanced blockchain interoperability. -- [Connect Theme & UI Customization](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/configure-theme.md): Learn how to style Wormhole Connect with custom color schemes, fonts, layouts, and menus for a streamlined user experience. -- [Wormhole Connect](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/configuration/index.md): Wormhole Connect is a React widget offering an easy-to-use interface to facilitate cross-chain asset transfers via Wormhole directly in a web application. -- [Connect FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/faqs.md): Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. -- [Features](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/features.md): Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. -- [Wormhole Connect](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/index.md): Wormhole Connect is a React widget offering an easy-to-use interface to facilitate multichain asset transfers via Wormhole directly in a web application. -- [Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/overview.md): Explore Wormhole Connect, the React widget that allows you to offer an easy-to-use UI for cross-chain asset transfers via Wormhole in a web application. -- [Routes](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/routes.md): Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. -- [Wormhole Connect v1.0 Migration Guide](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/connect/upgrade.md): Learn how to migrate to Wormhole Connect v1.0, with step-by-step guidance on updating your package and configuration. -- [Multichain Transfers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/index.md): This section guides you through using Wormhole products to securely and efficiently transfer assets and messages across multiple blockchains. -- [NTT CLI Commands](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/cli-commands.md): A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. -- [Native Token Transfers Access Control](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/access-control.md): Learn about the owner and pauser access roles for the NTT manager contract, which can be used to pause and un-pause token transfers. -- [Native Token Transfers (NTT) - Configuration](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/index.md): This section contains information on configuring Native Token Transfers (NTT), including guidance on setting Owner and Pauser access control roles and management of rate-limiting. -- [Native Token Transfers Rate Limiting](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/configuration/rate-limiting.md): Learn about rate limits in Wormhole NTT by configuring send/receive limits, queuing, and canceling flows to manage multichain token transfers efficiently. -- [Native Token Transfers EVM Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-evm.md): Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. -- [Native Token Transfers Solana Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md): Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. -- [Deploy Native Token Transfers with Launchpad](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md): Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. -- [Native Token Transfers (NTT) - Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/index.md): This section provides information on installing Wormhole's Native Token Transfer framework, deployment to EVM and Solana, and post deployment NTT maintenance. -- [Native Token Transfers Installation](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/installation.md): Learn how to Install Wormhole’s Native Token Transfers (NTT) framework, a flexible and composable framework for transferring tokens across blockchains. -- [Native Token Transfers Post Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/post-deployment.md): Learn post-deployment guidelines for optimizing Wormhole NTT, which include testing, security, frontend integration, ecosystem coordination, and monitoring. -- [Troubleshooting NTT Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/deployment-process/troubleshooting.md): Resolve common issues in NTT deployment with this troubleshooting guide covering Solana, EVM, mint authority, decimals, and rate limits. -- [Native Token Transfers FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/faqs.md): Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. -- [Native Token Transfers (NTT)](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/index.md): This section provides comprehensive guidance on configuring, deploying, and managing your Native Token Transfers (NTT) integration. -- [Managers and Transceivers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/native-token-transfers/managers-transceivers.md): Explore the roles of Managers and Transceivers in NTT cross-chain token transfers, including key functions, lifecycle events, and rate-limiting mechanisms. -- [Wormhole Settlement FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/faqs.md): Frequently asked questions about Wormhole Settlement, including smart contract usage, auction fallback, and message execution. -- [Wormhole Settlement](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/index.md): Start building with Wormhole Settlement; integrate with the Liquidity Layer and set up Solvers to enable seamless cross-chain asset transfers. -- [Wormhole Settlement Liquidity Layer](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/liquidity-layer.md): Learn how to build on the Wormhole Liquidity Layer, the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems. -- [Wormhole Settlement Solver](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/settlement/solver.md): Set up, configure, and run a Wormhole Settlement Solver on Solana's Matching Engine to fulfill cross-chain transfers efficiently and securely. -- [Get Started with Token Bridge](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/build/transfers/token-bridge.md): Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. -- [Glossary](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/glossary.md): Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. -- [MultiGov Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/architecture.md): Discover MultiGov's hub-and-spoke architecture, enabling secure cross-chain governance with Wormhole’s interoperability and decentralized coordination. -- [MultiGov Theoretical FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/faq.md): Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. -- [Learn about MultiGov](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/index.md): Explore the MultiGov documentation for a comprehensive guide covering architecture, deployment, upgrading, integration, and FAQs. -- [MultiGov Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/governance/overview.md): Explore MultiGov, a cross-chain governance system using Wormhole for seamless voting and proposal execution across multiple blockchain networks. -- [Learn about Wormhole](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/index.md): Learn the basics of Wormhole, covering its architecture, messaging protocols, and how it enables multichain communication and asset transfers. -- [Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/architecture.md): Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. -- [Core Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/core-contracts.md): Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. -- [Guardians](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/guardians.md): Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. -- [Infrastructure Components](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/index.md): Explore Wormhole's infrastructure, including the key components that enable secure multichain communication and asset transfers across blockchain networks. -- [Relayers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/relayer.md): Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. -- [Spy](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/spy.md): Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. -- [VAAs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/infrastructure/vaas.md): Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. -- [Introduction to Wormhole](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/introduction.md): Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. -- [Security](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/security.md): Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. -- [Circle's CCTP Bridge](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/cctp.md): Unlock fast USDC transfers with Wormhole's integration of Circle's CCTP, featuring automatic relaying via the Wormhole relayer and native gas solutions. -- [Multichain Transfers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/index.md): This section introduces the core messaging protocols that power seamless multichain communication and asset transfer within the Wormhole ecosystem. -- [Native Token Transfers Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/architecture.md): Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. -- [Native Token Transfers - Deployment Models](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/deployment.md): Explore Wormhole's Native Token Transfers deployment models——hub-and-spoke, burn-and-mint——for seamless cross-chain token transfers. -- [A Quick Look at Native Token Transfers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/index.md): This section covers Wormhole's Native Token Transfers (NTT), an open source, flexible, and composable framework for transferring tokens across blockchains. -- [Native Token Transfers Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/overview.md): Explore Wormhole's Native Token Transfers for flexible cross-chain transfers with full control over token behavior, security, and integration features. -- [Native Token Transfers Security](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/native-token-transfers/security.md): Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. -- [Settlement Protocol Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/architecture.md): Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. -- [Wormhole Settlement](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/index.md): Learn about Wormhole Settlement, an intent-based solution enabling fast and efficient asset transfers across Ethereum, Solana, Sui, and more. -- [Wormhole Settlement Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/settlement/overview.md): Discover Wormhole Settlement, enabling fast, intent-based asset transfers across Ethereum, Solana, Sui, and more for institutions and builders. -- [Token Bridge](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/learn/transfers/token-bridge.md): Learn about Wormhole's Token Bridge for cross-chain transfers using lock and mint mechanisms, ensuring secure and efficient asset movement. -- [Wormhole Connect Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/index.md): Enable cross-chain connectivity with Wormhole Connect. Learn integration and simplify user experiences across multiple blockchains. -- [Integrate Connect into a React DApp Tutorial](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/connect/react-dapp.md): Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. -- [Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/index.md): Discover product-specific Wormhole tutorials. Learn setup, integration, and advanced features to develop cross-chain apps confidently. -- [Multichain Assets Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multichain-assets/index.md): Explore comprehensive, step-by-step tutorials on how to register, manage, and work with multichain assets within the Wormhole ecosystem. -- [Create Multichain Tokens](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multichain-assets/multichain-token.md): Learn how to create a multichain token, bridge tokens across blockchains, and update metadata for seamless multichain interoperability. -- [Step-by-Step MultiGov Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov/index.md): Access step-by-step guides for executing cross-chain governance actions, including treasury management proposals with MultiGov and Wormhole. -- [MultiGov Guides](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/multigov/treasury-proposal.md): Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. -- [Wormhole Settlement](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/settlement/.index.md): Follow step-by-step tutorials to integrate Wormhole Settlement Routes using the SDK for seamless cross-chain swaps and efficient asset transfers. -- [Wormhole Settlements](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/settlement/.settlement-routes.md): Learn how to integrate Wormhole Settlement Routes using the SDK to simplify cross-chain swaps, manage fees, and execute seamless transactions. -- [Create Cross-Chain Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/cross-chain-contracts.md): Learn how to create cross-chain contracts using Wormhole's Solidity SDK. Deploy contracts on Avalanche and Celo Testnets and send messages across chains. -- [Cross-Chain Token Transfers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/cross-chain-token-contracts.md): Learn how to create cross-chain token transfers using Wormhole's Solidity SDK. Build and deploy smart contracts to send tokens from one blockchain to another. -- [Solidity SDK Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/solidity-sdk/index.md): Master cross-chain smart contracts with Wormhole's Solidity SDK. Learn messaging, token transfers, and secure, scalable dApp deployments across blockchains. -- [Wormhole SDK Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/index.md): Master the Wormhole SDK. Build robust cross-chain dApps with messaging, token bridging, and governance across multiple networks. -- [Transfer Tokens via Token Bridge Tutorial](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/tokens-via-token-bridge.md): Learn to build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains -- [Transfer USDC via CCTP and Wormhole SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/typescript-sdk/usdc-via-cctp.md): Learn how to perform USDC cross-chain transfers using Wormhole SDK and Circle's CCTP. Supports manual, automatic, and partial transfer recovery. -- [Wormholescan API Tutorials](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/wormholescan/index.md): Explore step-by-step guides on using the Wormholescan API to fetch VAAs, validate signatures, check redemption status, and process cross-chain transactions. -- [Replace Outdated Signatures in VAAs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tutorials/wormholescan/replace-signatures.md): Learn how to fetch, validate, and replace outdated signatures in Wormhole VAAs using Wormholescan and the Wormhole SDK to ensure seamless processing. \ No newline at end of file +- [AI Resources](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/ai-resources/ai-resources.md): Download LLM-optimized files of the Wormhole documentation, including full content and category-specific resources for AI agents. +- [Get Started with CCTP](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/get-started.md): Transfer USDC across chains using Wormhole's CCTP integration with the TypeScript SDK, including setup, attestation, and redemption steps. +- [Interacting with CCTP Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/guides/cctp-contracts.md): Learn how to interact directly with Circle's CCTP Bridge contracts, including TokenMessenger, TokenMinter, and MessageTransmitter. +- [CCTP Bridge with Wormhole](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/overview.md): Learn how the integration of Circle's CCTP with Wormhole enables secure and efficient native USDC transfers and complex cross-chain interactions. +- [Complete USDC Transfer Flow](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/cctp-bridge/tutorials/complete-usdc-transfer.md): Learn how to perform USDC cross-chain transfers using Wormhole SDK and Circle's CCTP. Supports manual, automatic, and partial transfer recovery. +- [Routes](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/concepts/routes.md): Explore Wormhole Connect's routing capabilities for asset transfers, featuring Token Bridge, CCTP, NTT, and various blockchain-specific routes for optimal UX. +- [Configure Your Connect Widget v0](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/configuration-v0.md): Configure Wormhole Connect v0 for React or HTML, set themes, define tokens, networks, and customize RPC endpoints for optimized blockchain interactions. +- [Connect Data Configuration](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/data.md): Configure Wormhole Connect v1 (latest) with custom chains, tokens, routes, and more for enhanced blockchain interoperability. +- [Connect Theme & UI Customization](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/configuration/theme.md): Learn how to style Wormhole Connect with custom color schemes, fonts, layouts, and menus for a streamlined user experience. +- [Connect FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/faqs.md): Common questions and detailed answers about using Wormhole Connect, including supported assets, chains, customization, and integration options. +- [Get Started with Connect](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/get-started.md): Follow this guide to configure and use the Connect UI widget to easily add an intuitive, multichain asset transfer UI to your web applications. +- [Integrate Connect via CDN](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/hosted-version.md): None +- [Wormhole Connect v1.0 Migration Guide](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/guides/upgrade.md): Learn how to migrate to Wormhole Connect v1.0, with step-by-step guidance on updating your package and configuration. +- [Wormhole Connect](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/overview.md): With Wormhole Connect, you can seamlessly bridge digital assets and data across a wide range of supported blockchain networks. +- [Features](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/reference/support-matrix.md): Explore a comprehensive Feature Support matrix and explain Wormhole's capabilities across networks for Token Bridge, CCTP, ETH Bridge, and more. +- [Integrate Connect into a React DApp Tutorial](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/connect/tutorials/react-dapp.md): Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. +- [Get Started with Messaging](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/get-started.md): Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +- [Get Started with Core Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/core-contracts.md): This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts +- [Wormhole-Deployed Relayers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/guides/wormhole-relayers.md): Learn about the Wormhole-deployed relayer configuration for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. +- [Messaging Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/overview.md): With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +- [Create Cross-Chain Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/cross-chain-contracts.md): Learn how to create cross-chain contracts using Wormhole's Solidity SDK. Deploy contracts on Avalanche and Celo Testnets and send messages across chains. +- [Cross-Chain Token Transfers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/cross-chain-token-contracts.md): Learn how to create cross-chain token transfers using Wormhole's Solidity SDK. Build and deploy smart contracts to send tokens from one blockchain to another. +- [Replace Outdated Signatures in VAAs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/messaging/tutorials/replace-signatures.md): Learn how to fetch, validate, and replace outdated signatures in Wormhole VAAs using Wormholescan and the Wormhole SDK to ensure seamless processing. +- [MultiGov Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/concepts/architecture.md): Discover MultiGov's hub-and-spoke architecture, enabling secure cross-chain governance with Wormhole’s interoperability and decentralized coordination. +- [MultiGov FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/faqs.md): Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. +- [Get Started with Multigov](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/get-started.md): Follow this guide to set up your environment and request access to deploy MultiGov contracts for multichain DAO governance using Wormhole messaging. +- [Deploy MultiGov on EVM Chains](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-evm.md): Set up and deploy MultiGov to EVM locally with step-by-step instructions for configuring, compiling, and deploying smart contracts across chains. +- [MultiGov Deployment to Solana](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/deploy-to-solana.md): Learn how to deploy the MultiGov Staking Program on Solana, including setup, funding, deployment, and configuration steps. +- [Upgrading MultiGov on EVM](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-evm.md): Learn the process and key considerations for upgrading MultiGov on EVM, ensuring system integrity and careful planning across cross-chain components. +- [Upgrading MultiGov on Solana](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/guides/upgrade-solana.md): Learn the process and key considerations for upgrading MultiGov on Solana, ensuring system integrity and careful planning across cross-chain components. +- [MultiGov Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/overview.md): Enable multichain governance with MultiGov. Create, vote, and execute DAO proposals securely across Wormhole supported networks. +- [MultiGov Guides](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/multigov/tutorials/treasury-proposal.md): Learn how to initiate a proposal on a hub chain, vote from spoke chains, aggregate the votes, and finally execute the proposal using Wormhole's MultiGov. +- [Native Token Transfers Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/architecture.md): Explore Wormhole's Native Token Transfers architecture, which covers components, message flow, rate limiting, and custom transceivers. +- [Native Token Transfers Security](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/concepts/security.md): Explore the security measures of Native Token Transfers, including the Global Accountant and governance strategies for seamless token safety. +- [Native Token Transfers Access Control](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/access-control.md): Learn about the owner and pauser access roles for the NTT manager contract, which can be used to pause and un-pause token transfers. +- [Native Token Transfers Rate Limiting](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/configuration/rate-limiting.md): Learn about rate limits in Wormhole NTT by configuring send/receive limits, queuing, and canceling flows to manage multichain token transfers efficiently. +- [Native Token Transfers FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/faqs.md): Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. +- [Get Started with NTT](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/get-started.md): NTT enables cross-chain token movement without wrapping. Install the CLI, deploy test tokens, and scaffold a project to integrate NTT into your app. +- [Native Token Transfers EVM Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-evm.md): Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. +- [Native Token Transfers Solana Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/deploy-to-solana.md): Deploy and configure Wormhole's Native Token Transfers (NTT) for Solana, including setup, token compatibility, mint/burn modes, and CLI usage. +- [Deploy Native Token Transfers with Launchpad](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/evm-launchpad.md): Deploy a new token or extend an existing one across multiple chains with the NTT Launchpad. Manage transfers, supply, and settings—all from a single platform. +- [Native Token Transfers Post Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/post-deployment.md): Learn post-deployment guidelines for optimizing Wormhole NTT, which include testing, security, frontend integration, ecosystem coordination, and monitoring. +- [Troubleshooting NTT Deployment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/guides/troubleshoot.md): Resolve common issues in NTT deployment with this troubleshooting guide covering Solana, EVM, mint authority, decimals, and rate limits. +- [Native Token Transfers Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/overview.md): With Native Token Transfers, you can directly transfer a blockchain's native assets across various connected networks. +- [NTT CLI Commands](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/cli-commands.md): A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +- [Managers and Transceivers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/native-token-transfers/reference/managers-transceivers.md): Explore the roles of Managers and Transceivers in NTT cross-chain token transfers, including key functions, lifecycle events, and rate-limiting mechanisms. +- [Compare Wormhole's Cross-Chain Solutions](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/products.md): Compare Wormhole’s cross-chain solutions for bridging, native transfers, data queries, and governance to enable seamless blockchain interoperability. +- [Queries FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/faqs.md): Wormhole Queries FAQ covering available libraries, query examples, response formats, and details about running query proxy servers. +- [Get Started with Queries](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/get-started.md): Follow this guide to run your first multichain, verifiable query with the Wormhole Queries SDK and Proxy, using eth_call to fetch token metadata. +- [Use Queries](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/guides/use-queries.md): Explore a simple demo of interacting with Wormhole Queries using an eth_call request to query the supply of wETH on Ethereum using a Wormhole query. +- [Queries Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/overview.md): Learn how Wormhole Queries enable smart contracts to fetch real-time, Guardian-verified data across multiple blockchains. +- [Queries Supported Methods](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-methods.md): Retrieve multichain data via historical timestamp queries, finality confirmation queries, and Solana lookups. +- [Queries Supported Networks](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/queries/reference/supported-networks.md): Reference table of chains supported by Wormhole Queries, including method support, finality, and expected historical data availability. +- [Chain IDs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/chain-ids.md): This page documents the Wormhole-specific chain IDs for each chain and contrasts them to the more commonly referenced EVM chain IDs originating in EIP-155. +- [Wormhole Finality | Consistency Levels](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/consistency-levels.md): This page documents how long to wait for finality before signing, based on each chain’s consistency (finality) level and consensus mechanism. +- [Contract Addresses](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/contract-addresses.md): This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. +- [Glossary](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/glossary.md): Explore a comprehensive glossary of technical terms and key concepts used in the Wormhole network, covering Chain ID, Guardian, VAA, and more. +- [Supported Networks](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/supported-networks.md): Learn about the networks each Wormhole product supports, and explore links to documentation, official websites, and block explorers. +- [Testnet Faucets](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/testnet-faucets.md): This page includes resources to quickly find the Testnet tokens you need to deploy and test applications and contracts on Wormhole's supported networks. +- [Wormhole Formatted Addresses](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/reference/wormhole-formatted-addresses.md): Explanation of Wormhole formatted 32-byte hex addresses, their conversion, and usage across different blockchain platforms. +- [Settlement Protocol Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/concepts/architecture.md): Explore Wormhole Settlement's native swap protocols—Liquidity Layer, Mayan Swift, and MCTP—for scalable, efficient cross-chain asset transfers. +- [Wormhole Settlement FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/faqs.md): Frequently asked questions about Wormhole Settlement, including smart contract usage, auction fallback, and message execution. +- [Get Started](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/get-started.md): Perform a cross-chain token swap using Wormhole Settlement and the Mayan Swift route with the TypeScript SDK on mainnet. +- [Settlement Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/settlement/overview.md): Discover how Settlement enables fast, intent-based token transfers across chains using a unified system of solver auctions and integrated execution routes. +- [Token Bridge Payload Structure](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/payload-structure.md): Discover the structure and purpose of each Token Bridge payload, including Transfer, TransferWithPayload, AssetMeta, and governance messages. +- [Flow of a Token Bridge Transfer](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/concepts/transfer-flow.md): Learn how the Wormhole Token Bridge enables secure, cross-chain token transfers by combining token-specific logic with Wormhole's core message-passing layer. +- [Token Bridge FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/faqs.md): Find answers to common questions about the Wormhole Token Bridge, including managing wrapped assets and understanding gas fees. +- [Get Started with Token Bridge](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/get-started.md): Perform token transfers using Wormhole’s Token Bridge with the TypeScript SDK, including manual (Solana–Sepolia) and automatic (Fuji–Alfajores). +- [Get Started with Token Bridge](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/guides/token-bridge-contracts.md): Learn how to integrate Wormhole's Token Bridge for seamless multichain token transfers with a lock-and-mint mechanism and cross-chain asset management. +- [Token Bridge Overview](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/overview.md): With Wormhole Token Bridge, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +- [Create Multichain Tokens](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/tutorials/multichain-token.md): Learn how to create a multichain token, bridge tokens across blockchains, and update metadata for seamless multichain interoperability. +- [Transfer Tokens via Token Bridge Tutorial](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/products/token-bridge/tutorials/transfer-workflow.md): Learn to build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains +- [Architecture](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/architecture.md): Overview of Wormhole's architecture, detailing key on-chain and off-chain components like the Core Contract, Guardian Network, and relayers. +- [Ecosystem](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/ecosystem.md): Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +- [Run a Relayer](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure-guides/run-relayer.md): Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. +- [Run a Spy](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure-guides/run-spy.md): Learn how to run a Spy locally to listen for and forward messages (Verifiable Action Approvals, or VAAs) published on the Wormhole network. +- [Core Contracts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/core-contracts.md): Discover Wormhole's Core Contracts, which enable multichain communication with message sending, receiving, and multicast features for efficient synchronization. +- [Guardians](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/guardians.md): Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. +- [Relayers](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/relayer.md): Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. +- [Spy](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/spy.md): Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. +- [VAAs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/infrastructure/vaas.md): Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and role in cross-chain communication. +- [Introduction to Wormhole](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/introduction.md): Wormhole is a protocol for seamless communication between blockchains, enabling cross-chain applications and integrations. +- [Security](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/protocol/security.md): Explore Wormhole's security features, including the Guardian network, governance, monitoring, open-source development, and bug bounty programs. +- [Wormhole CLI](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/cli/get-started.md): Learn how to install and use the Wormhole CLI, including commands and examples for managing multichain deployments, generating VAAs, and querying contract info. +- [Local Dev Environment](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/dev-env.md): Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more. +- [Toolkit FAQs](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/faqs.md): FAQs on Wormhole Toolkit, covering Wormholescan, CLI, SDKs (TypeScript, Solidity), Tilt, error handling, transaction history, and manual VAA submission. +- [Get Started with the Solidity SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/get-started.md): Follow this guide to use the Wormhole Solidity SDK's interfaces and tools to help you quickly build on-chain integrations using smart contracts. +- [Solidity SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/solidity-sdk/sdk-reference.md): How to use the Wormhole Solidity SDK for cross-chain messaging, token transfers, and integrating decentralized applications on EVM-compatible blockchains. +- [Get Started with the TypeScript SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/get-started.md): Follow this guide to install the Wormhole TypeScript SDK, initialize a Wormhole instance, and add the platforms your integration supports. +- [Building Protocols and Payloads](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/protocols-payloads.md): Learn how to build, register, and integrate protocols and payloads in the Wormhole TypeScript SDK with type-safe layouts. +- [Data Layouts](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/sdk-layout.md): Learn how to efficiently define, serialize, and deserialize data structures using Wormhole SDK's layout system for cross-chain communication. +- [VAAs and Protocols](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/guides/vaas-protocols.md): Understand how VAAs enable cross-chain messaging and how to handle them using Wormhole's TypeScript and Solidity SDKs. +- [Wormhole TS SDK](https://raw.githubusercontent.com/wormhole-foundation/wormhole-docs/refs/heads/main/tools/typescript-sdk/sdk-reference.md): Explore Wormhole's TypeScript SDK and learn how to perform different types of transfers, including native, token, and USDC. \ No newline at end of file diff --git a/products/.pages b/products/.pages new file mode 100644 index 000000000..7a3d070ff --- /dev/null +++ b/products/.pages @@ -0,0 +1,11 @@ +nav: + - 'Product Overview': products.md + - connect + - native-token-transfers + - settlement + - token-bridge + - cctp-bridge + - multigov + - queries + - messaging + - reference diff --git a/products/cctp-bridge/.pages b/products/cctp-bridge/.pages new file mode 100644 index 000000000..4eeee24e9 --- /dev/null +++ b/products/cctp-bridge/.pages @@ -0,0 +1,6 @@ +title: CCTP Bridge +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- tutorials diff --git a/products/cctp-bridge/get-started.md b/products/cctp-bridge/get-started.md new file mode 100644 index 000000000..c540e6cfd --- /dev/null +++ b/products/cctp-bridge/get-started.md @@ -0,0 +1,88 @@ +--- +title: Get Started with CCTP +description: Transfer USDC across chains using Wormhole's CCTP integration with the TypeScript SDK, including setup, attestation, and redemption steps. +categories: Transfer +--- + +# Get Started with CCTP + +## Introduction + +[Wormhole CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} enables native USDC transfers between supported chains by burning tokens on the source chain and minting them on the destination. This provides native, canonical USDC movement without the need for wrapped tokens. + +In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform a manual cross-chain USDC transfer using Circle's CCTP protocol. + +You will initiate the transfer on the source chain, wait for Circle's attestation, and redeem the USDC on the destination chain. + +## Prerequisites + +Before you begin, make sure you have the following: + + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with native tokens and USDC on two [supported CCTP chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} + +This example uses an Avalanche Fuji wallet with [USDC](https://faucet.circle.com/){target=\_blank} and [AVAX](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank}, as well as a Sepolia wallet with testnet [ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank}, to pay the transaction fees. You can adapt the steps to work with any [supported EVM chains](/docs/products/reference/supported-networks/#cctp){target=\_blank} that support CCTP. + +## Configure Your Token Transfer Environment + +1. Create a new directory and initialize a Node.js project: + + ```bash + mkdir cctp-bridge + cd cctp-bridge + npm init -y + ``` + +2. Install the required dependencies: + + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` + +3. Create a `transfer.ts` file to handle the multichain transfer logic and a `helper.ts` file to manage wallet signers: + + ```bash + touch transfer.ts helper.ts + ``` + +4. Set up secure access to your wallets. This guide assumes you are loading your `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +## Perform a CCTP Transfer + +This section walks you through a complete manual USDC transfer using Wormhole's CCTP integration. You will initiate the transfer on Avalanche Fuji, wait for the Circle attestation, and complete the redemption on Sepolia. + +Start by defining utility functions for signer and token setup: + +1. In `helper.ts`, define functions to load private keys and instantiate EVM signers: + + ```ts title="helper.ts" + --8<-- "code/products/cctp-bridge/get-started/snippet-1.ts" + ``` + +2. In `transfer.ts`, add the script to perform the manual transfer using CCTP: + + ```ts title="transfer.ts" + --8<-- "code/products/cctp-bridge/get-started/snippet-2.ts" + ``` + +3. Run the script to execute the transfer: + + ```bash + npx tsx transfer.ts + ``` + + You will see terminal output similar to the following: + + --8<-- "code/products/cctp-bridge/get-started/snippet-3.html" + +To verify the transaction and view its details, paste the transaction hash into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. + +## Next Steps + +Now that you've completed a CCTP USDC transfer using the Wormhole SDK, you're ready to explore more advanced features and expand your integration: + + - [**Circle CCTP Documentation**](https://developers.circle.com/stablecoins/cctp-getting-started): Learn how USDC cross-chain transfers work and explore advanced CCTP features. \ No newline at end of file diff --git a/products/cctp-bridge/guides/.pages b/products/cctp-bridge/guides/.pages new file mode 100644 index 000000000..a74182f73 --- /dev/null +++ b/products/cctp-bridge/guides/.pages @@ -0,0 +1,3 @@ +title: Guides +nav: +- 'Interact with Contracts': cctp-contracts.md diff --git a/build/transfers/cctp.md b/products/cctp-bridge/guides/cctp-contracts.md similarity index 93% rename from build/transfers/cctp.md rename to products/cctp-bridge/guides/cctp-contracts.md index ac38445ab..1fc825f70 100644 --- a/build/transfers/cctp.md +++ b/products/cctp-bridge/guides/cctp-contracts.md @@ -4,11 +4,11 @@ description: Learn how to interact directly with Circle's CCTP Bridge contracts, categories: Transfer --- -# Get Started with CCTP +# Interact with CCTP Contracts ## Introduction -Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/learn/transfers/cctp/){target=\_blank} by Circle is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. +Circle's [Cross-Chain Transfer Protocol (CCTP)](/docs/products/cctp-bridge/overview/){target=\_blank} is a permissionless utility that facilitates secure and efficient USDC transfers across blockchain networks through native burning and minting mechanisms. As decentralized finance (DeFi) protocols evolve, the need for flexible, secure cross-chain messaging has expanded, requiring solutions beyond simple asset transfers. Wormhole enhances CCTP's capabilities by allowing developers to compose more complex cross-chain interactions. With Wormhole's generic messaging, applications can execute smart contract logic alongside native USDC transfers, enabling richer, more versatile cross-chain experiences. @@ -18,8 +18,8 @@ This guide will walk you through getting started with Wormhole's CCTP contracts To interact with the Wormhole CCTP, you'll need the following: -- [The address of the CCTP contract](/docs/build/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- [The address of the CCTP contract](/docs/products/reference/contract-addresses/#cctp){target=\_blank} on the chains you're deploying your contract on +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on ## Wormhole's CCTP Integration Contract @@ -30,11 +30,11 @@ The Circle Integration contract emits Wormhole messages with arbitrary payloads This contract can be found in [Wormhole's `wormhole-circle-integration` repository](https://github.com/wormhole-foundation/wormhole-circle-integration/){target=\_blank} on GitHub. !!! note - Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/build/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. + Wormhole supports all CCTP-supported chains, but Circle currently supports only a [handful of chains](https://developers.circle.com/stablecoins/docs/supported-domains){target=\_blank}. Please refer to the [CCTP section of the Contract Addresses](/docs/products/reference/contract-addresses/#cctp){target=\_blank} reference page to view the complete list of supported chains. ??? code "Circle Integration contract" ```solidity - --8<-- 'code/build/transfers/cctp/CircleIntegration.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/CircleIntegration.sol' ``` The functions provided by the Circle Integration contract are as follows: @@ -216,7 +216,7 @@ Additionally, the contract provides methods for updating or replacing previously ??? code "Token Messenger contract" ```solidity - --8<-- 'code/build/transfers/cctp/TokenMessenger.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/TokenMessenger.sol' ``` This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMessenger.sol){target=\_blank} on GitHub. @@ -259,7 +259,7 @@ The functions provided by the Token Messenger contract are as follows: `DepositForBurn` - event emitted when `depositForBurn` is called. The `destinationCaller` is set to `bytes32(0)` to allow any address to call `receiveMessage` on the destination domain - --8<-- 'text/build/transfers/cctp/DepositForBurn-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/DepositForBurn-event.md' - **`depositForBurnWithCaller`** - deposits and burns tokens from the sender to be minted on the destination domain. This method differs from `depositForBurn` in that the mint on the destination domain can only be called by the designated `destinationCaller` address @@ -303,7 +303,7 @@ The functions provided by the Token Messenger contract are as follows: `DepositForBurn` - event emitted when `depositForBurnWithCaller` is called - --8<-- 'text/build/transfers/cctp/DepositForBurn-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/DepositForBurn-event.md' - **`replaceDepositForBurn`** — replaces a previous `BurnMessage` to modify the mint recipient and/or the destination caller. The replacement message reuses the `_nonce` created by the original message, which allows the original message's sender to update the details without requiring a new deposit @@ -339,7 +339,7 @@ The functions provided by the Token Messenger contract are as follows: `DepositForBurn` - event emitted when `replaceDepositForBurn` is called. Note that the `destinationCaller` will reflect the new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (`bytes32(0)`), indicating that any destination caller is valid - --8<-- 'text/build/transfers/cctp/DepositForBurn-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/DepositForBurn-event.md' - **`handleReceiveMessage`** - handles an incoming message received by the local `MessageTransmitter` and takes the appropriate action. For a burn message, it mints the associated token to the requested recipient on the local domain. @@ -415,7 +415,7 @@ Additional features include replacing previously sent messages, setting maximum ??? code "Message Transmitter contract" ```solidity - --8<-- 'code/build/transfers/cctp/MessageTransmitter.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/MessageTransmitter.sol' ``` This contract and the interfaces, contracts, and libraries it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol){target=\_blank} on GitHub. @@ -504,7 +504,7 @@ The functions provided by the Message Transmitter contract are as follows: ??? interface "Emits" - --8<-- 'text/build/transfers/cctp/MessageSent-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/MessageSent-event.md' - **`sendMessageWithCaller`** — sends a message to the destination domain and recipient, requiring a specific caller to trigger the message on the target chain. It increments the `nonce`, assigns a unique `nonce` to the message, and emits a `MessageSent` event @@ -540,7 +540,7 @@ The functions provided by the Message Transmitter contract are as follows: ??? interface "Emits" - --8<-- 'text/build/transfers/cctp/MessageSent-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/MessageSent-event.md' - **`replaceMessage`** — replaces an original message with a new message body and/or updates the destination caller. The replacement message reuses the `_nonce` created by the original message @@ -574,7 +574,7 @@ The functions provided by the Message Transmitter contract are as follows: ??? interface "Emits" - --8<-- 'text/build/transfers/cctp/MessageSent-event.md' + --8<-- 'text/products/cctp-bridge/guides/cctp-contracts/MessageSent-event.md' ### Token Minter Contract @@ -586,7 +586,7 @@ To enhance control and flexibility, the contract includes mechanisms to pause op ??? code "Token Minter contract" ```solidity - --8<-- 'code/build/transfers/cctp/TokenMinter.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/TokenMinter.sol' ``` This contract and the interfaces and contracts it relies on are stored in [Circle's `evm-cctp-contracts` repository](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/TokenMinter.sol){target=\_blank} on GitHub. @@ -629,13 +629,13 @@ To streamline this process, you can use the [Wormhole Solidity SDK](https://gith ??? code "CCTP Sender contract" ```solidity - --8<-- 'code/build/transfers/cctp/CCTPSender.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/CCTPSender.sol' ``` The `CCTPSender` abstract contract exposes the `sendUSDCWithPayloadToEvm` function. This function publishes a CCTP transfer of the provided `amount` of USDC and requests that the transfer be delivered along with a `payload` to the specified `targetAddress` on the `targetChain`. ```solidity ---8<-- 'code/build/transfers/cctp/sendUSDCWithPayloadToEvm.sol' +--8<-- 'code/products/cctp-bridge/guides/cctp-contracts/sendUSDCWithPayloadToEvm.sol' ``` ??? interface "Parameters" @@ -696,7 +696,7 @@ When the `sendUSDCWithPayloadToEvm` function is called, the following series of A simple example implementation is as follows: ```solidity ---8<-- 'code/build/transfers/cctp/sendCrossChainDeposit.sol' +--8<-- 'code/products/cctp-bridge/guides/cctp-contracts/sendCrossChainDeposit.sol' ``` The above example sends a specified amount of USDC and the recipient's address as a payload to a target contract on another chain, ensuring that the correct cost is provided for the cross-chain transfer. @@ -710,7 +710,7 @@ Using the Wormhole-deployed relayer automatically triggers the `receiveWormholeM ??? code "CCTP Receiver contract" ```solidity - --8<-- 'code/build/transfers/cctp/CCTPReceiver.sol' + --8<-- 'code/products/cctp-bridge/guides/cctp-contracts/CCTPReceiver.sol' ``` Although you do not need to interact with the `receiveWormholeMessages` function directly, it's important to understand what it does. This function processes cross-chain messages and USDC transfers via Wormhole's Circle (CCTP) Bridge. Here's a summary of what it does: @@ -727,7 +727,7 @@ Although you do not need to interact with the `receiveWormholeMessages` functi You'll need to implement the `receivePayloadAndUSDC` function to transfer the USDC and handle the payload as your application needs. A simple example implementation is as follows: ```solidity ---8<-- 'code/build/transfers/cctp/receivePayloadAndUSDC.sol' +--8<-- 'code/products/cctp-bridge/guides/cctp-contracts/receivePayloadAndUSDC.sol' ``` ## Complete Example diff --git a/products/cctp-bridge/overview.md b/products/cctp-bridge/overview.md new file mode 100644 index 000000000..be38edbd0 --- /dev/null +++ b/products/cctp-bridge/overview.md @@ -0,0 +1,79 @@ +--- +title: CCTP Bridge with Wormhole +description: Learn how the integration of Circle's CCTP with Wormhole enables secure and efficient native USDC transfers and complex cross-chain interactions. +categories: Transfer +--- + +# CCTP with Wormhole Overview + +The integration of [Circle's Cross-Chain Transfer Protocol (CCTP)](https://www.circle.com/cross-chain-transfer-protocol){target=\_blank} with the Wormhole messaging protocol creates a robust system for securely and efficiently transferring native USDC across different blockchain networks while enabling more complex multichain interactions. This combination streamlines the movement of stablecoins, reduces risk, and unlocks new possibilities for decentralized applications. + +## Key Features + +- **Secure native USDC transfers**: At its core, CCTP provides a "burn-and-mint" mechanism for transferring native USDC. This eliminates the need for wrapped assets and the associated risks of intermediary bridges. +- **Atomic execution**: By combining CCTP and Wormhole, the transfer of USDC and the execution of accompanying instructions on the destination chain can occur as a single atomic transaction. +- **Automated relaying**: Eliminates the need for users to redeem USDC transfers themselves. +- **Enhanced composability**: Developers can build more sophisticated cross-chain applications by sending additional data alongside the transfer. +- **Gas drop off**: Enables users to convert a portion of USDC into the destination chain's gas token upon a successful transfer. +- **Gas payment**: Covering destination gas in automated vs. manual transfers. + - **Automated**: Users often don't need destination gas tokens upfront, relayers cover these gas costs, reimbursed via gas drop-off or initial fees. + - **Manual**: Users pay destination gas directly, the protocol may offer post-claim USDC-to-gas conversion. + +## How It Works + +This section outlines the end-to-end flow for transferring native USDC across chains using CCTP while optionally triggering an action on the destination chain. Circle and Wormhole coordinate each step to ensure a secure, verifiable transfer and execution process. + +1. **Alice initiates a transfer on Ethereum**: She submits a request to the Circle Bridge to send 100 USDC to Avalanche. If desired, she could include optional payload data. + +2. **Tokens are taken into custody and burned**: The Circle Bridge takes custody of Alice's USDC and initiates a burn using Circle's CCTP, triggering an off-chain attestation process. + +3. **A Wormhole message is published**: The transfer metadata is emitted as a Wormhole message. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate and sign it to produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. + +4. **A relayer automatically processes the messages**: Once the VAA and Circle attestation are available, a relayer submits them to the Circle Bridge on Avalanche. + +5. **Tokens are minted**: The Circle Bridge verifies both proofs and mints 100 USDC to Alice using Circle's CCTP. If a payload is included, it can be executed atomically. + +```mermaid +sequenceDiagram + participant User as Alice + participant SourceChain as Circle Bridge
on Ethereum + participant Circle + participant Guardians as Wormhole Guardians + participant Relayer + participant DestinationChain as Circle Bridge
on Avalanche + + User->>SourceChain: Submit transfer
(100 USDC to Avalanche) + SourceChain->>Circle: Initiate a burn + Circle->>Circle: Burn USDC and provide attestation + SourceChain->>Guardians: Emit Wormhole message (transfer metadata) + Guardians->>Guardians: Sign message and produce VAA + Relayer->>Guardians: Fetch signed VAA + Relayer->>Circle: Fetch Circle burn attestation + Relayer->>DestinationChain: Submit VAA and
attestation + DestinationChain->>Circle: Verify Circle attestation + Circle->>User: Mint USDC to Alice +``` + +!!! note + For a cross-chain transfer to be successful, both the source and destination chains must be among those supported by [Circle's CCTP](https://developers.circle.com/stablecoins/supported-domains){target=\_blank}. + +## Use Cases + +Integrating Wormhole's messaging with CCTP enables the secure transfer of native USDC across blockchains, unlocking key cross-chain use cases, which include: + +- **USDC Payments Across Chains** + - [**CCTP**](/docs/products/cctp-bridge/get-started/): Transfer native USDC using Circle’s burn-and-mint protocol. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Automate attestation delivery and gas handling. + - [**Connect**](/docs/products/connect/overview/): Embed multichain USDC transfers directly in your app. + +- **USDC-Powered Multichain Settlement** + - [**Settlement**](/docs/products/settlement/overview/): Use the Liquidity Layer to settle intents with native USDC. + - [**Wormhole TypeScript SDK**](/docs/tools/typescript-sdk/sdk-reference/): Initiate transfers, discover routes, and execute swaps seamlessly. + +## Next Steps + +Now that you're familiar with CCTP, here is a list of resources for more hands-on practice: + +- [**Get started with CCTP Bridge**](/docs/products/cctp-bridge/get-started/): Perform a multichain USDC transfer from Avalanche to Sepolia using Wormhole's TypeScript SDK and Circle's CCTP. +- [**Complete USDC Transfer Flow**](/docs/products/cctp-bridge/tutorials/complete-usdc-transfer/): Execute a USDC cross-chain transfer using Wormhole SDK and Circle's CCTP, covering manual, automatic, and partial transfer recovery. +- [**Checkout Circle's CCTP Docs**](https://developers.circle.com/stablecoins/cctp-getting-started){target=\_blank}: Learn more about Circle's cross-chain transfer protocol in their documentation. \ No newline at end of file diff --git a/products/cctp-bridge/tutorials/.pages b/products/cctp-bridge/tutorials/.pages new file mode 100644 index 000000000..dfdff76e5 --- /dev/null +++ b/products/cctp-bridge/tutorials/.pages @@ -0,0 +1,3 @@ +title: Tutorials +nav: +- 'Complete USDC Transfer Flow': complete-usdc-transfer.md diff --git a/tutorials/typescript-sdk/usdc-via-cctp.md b/products/cctp-bridge/tutorials/complete-usdc-transfer.md similarity index 88% rename from tutorials/typescript-sdk/usdc-via-cctp.md rename to products/cctp-bridge/tutorials/complete-usdc-transfer.md index c236ec0c8..df2f39d18 100644 --- a/tutorials/typescript-sdk/usdc-via-cctp.md +++ b/products/cctp-bridge/tutorials/complete-usdc-transfer.md @@ -1,15 +1,15 @@ --- -title: Transfer USDC via CCTP and Wormhole SDK +title: Complete USDC Transfer Flow description: Learn how to perform USDC cross-chain transfers using Wormhole SDK and Circle's CCTP. Supports manual, automatic, and partial transfer recovery. --- -# Transfer USDC via CCTP and Wormhole SDK +# Complete USDC Transfer Flow :simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-cctp-transfer){target=\_blank} ## Introduction -In this guide, we will show you how to bridge native USDC across different blockchain networks using [Circle's Cross-Chain Transfer Protocol](/docs/learn/transfers/cctp/){target=\_blank} (CCTP) and [Wormhole’s TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main){target=\_blank}. +In this guide, we will show you how to bridge native USDC across different blockchain networks using [Circle's Cross-Chain Transfer Protocol](/docs/products/cctp-bridge/overview/){target=\_blank} (CCTP) and [Wormhole’s TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts/tree/main){target=\_blank}. Traditionally, cross-chain transfers using CCTP involve multiple manual steps, such as initiating the transfer on the source chain, relaying messages between chains, and covering gas fees on both the source and destination chains. Without the TypeScript SDK, developers must handle these operations independently, adding complexity and increasing the chance for errors, mainly when dealing with gas payments on the destination chain and native gas token management. @@ -90,7 +90,7 @@ In this section, you'll set up your project for transferring USDC across chains 2. Open the `helpers.ts` file and add the following code ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-1.ts" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-1.ts" ``` - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file @@ -107,7 +107,7 @@ In this section, you'll set up your project for transferring USDC across chains 2. Open the `manual-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:1:4" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:1:4" ``` - **`evm`** - this import is for working with EVM-compatible chains, like Avalanche, Ethereum, Base Sepolia, and more @@ -129,7 +129,7 @@ Before initiating a cross-chain transfer, you must set up the chain context and 1. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM and Solana) to support. This allows us to interact with both EVM-compatible chains like Avalanche and non-EVM chains like Solana if needed ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:6:7" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:6:7" ``` !!! note @@ -138,25 +138,25 @@ Before initiating a cross-chain transfer, you must set up the chain context and 2. **Set up source and destination chains** - specify the source chain (Avalanche) and the destination chain (Sepolia) using the `getChain` method. This allows us to define where to send the USDC and where to receive them ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:10:11" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:10:11" ``` 3. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:14:15" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:14:15" ``` 4. **Define the transfer amount** - the amount of USDC to transfer is specified. In this case, we're transferring 0.1 USDC, which is parsed and converted into the base units expected by the Wormhole SDK ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:18:18" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:18:18" ``` 5. **Set transfer mode** - we specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:20:20" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:20:20" ``` #### Initiate the Transfer @@ -166,13 +166,13 @@ To begin the manual transfer process, you first need to create the transfer obje 1. **Create the Circle transfer object** - the `wh.circleTransfer()` function creates an object with the transfer details, such as the amount of USDC, the source and destination addresses, and the mode. However, this does not initiate the transfer itself ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:23:28" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:23:28" ``` 2. **Start the transfer** - the `initiateTransfer` function sends the transaction on the source chain. It involves signing and sending the transaction using the source signer. This will return a list of transaction IDs (`srcTxIds`) that you can use to track the transfer ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:34:35" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:34:35" ``` #### Fetch the Circle Attestation (VAA) @@ -183,13 +183,13 @@ Once you initialize the transfer on the source chain, you must fetch the VAA fro 1. **Set a timeout** - fetching the attestation can take some time, so setting a timeout is common. In this example, we set the timeout to 60 seconds ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:38:38" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:38:38" ``` 2. **Fetch the attestation** - after initiating the transfer, you can use the `fetchAttestation()` function to retrieve the VAA. This function will wait until the attestation is available or you reach the specified timeout ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:40:41" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:40:41" ``` The `attestIds` will contain the details of the fetched attestation, which Wormhole uses to complete the transfer on the destination chain @@ -201,7 +201,7 @@ Once you fetch the VAA correctly, the final step is to complete the transfer on Use the `completeTransfer()` function to finalize the transfer on the destination chain. This requires the destination signer to sign and submit the transaction to the destination chain ```typescript ---8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts:45:50" +--8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts:45:50" ``` The `dstTxIds` will hold the transaction IDs for the transfer on the destination chain, confirming that the transfer has been completed @@ -210,7 +210,7 @@ You can find the full code for the manual USDC transfer script below: ???- code "`manual-transfer.ts`" ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-2.ts" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-2.ts" ``` ### Run Manual Transfer @@ -234,7 +234,7 @@ This feature is handy for recovering an incomplete transfer or when debugging. Here’s how you can complete a partial transfer using just the source chain and transaction hash: ```typescript ---8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-4.ts:19:29" +--8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-4.ts:19:29" ``` You will need to provide the below requirements to complete the partial transfer: @@ -248,7 +248,7 @@ You can find the full code for the manual USDC transfer script below: ??? code "`partial-transfer.ts`" ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-4.ts" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-4.ts" ``` ## Automatic Transfers @@ -262,7 +262,7 @@ The automatic transfer process simplifies the steps by automating the attestatio The setup for automatic transfers is similar to manual transfers, with the key difference being that the `automatic` flag is `true`. This indicates that Wormhole will handle the attestation and finalization steps for you ```typescript ---8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts:21:21" +--8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts:21:21" ``` #### Initiate the Transfer @@ -270,7 +270,7 @@ The setup for automatic transfers is similar to manual transfers, with the key d The transfer process is the same as that for manual transfers. You create the transfer object and then start the transfer on the source chain ```typescript ---8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts:24:29" +--8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts:24:29" ``` #### Log Transfer Details @@ -278,14 +278,14 @@ The transfer process is the same as that for manual transfers. You create the tr After initiating the transfer, you can log the transaction IDs for both the source and destination chains. This will help you track the progress of the transfer ```typescript ---8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts:35:38" +--8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts:35:38" ``` You can find the full code for the automatic USDC transfer script below: ??? code "`automatic-transfer.ts`" ```typescript - --8<-- "code/tutorials/typescript-sdk/usdc-via-cctp/cctp-sdk-3.ts" + --8<-- "code/products/cctp-bridge/tutorials/complete-usdc-transfer/cctp-sdk-3.ts" ``` ### Run Automatic Transfer diff --git a/products/connect/.pages b/products/connect/.pages new file mode 100644 index 000000000..931e1c845 --- /dev/null +++ b/products/connect/.pages @@ -0,0 +1,10 @@ +title: Connect +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- configuration +- guides +- tutorials +- concepts +- 'FAQs': faqs.md +- reference \ No newline at end of file diff --git a/products/connect/concepts/.pages b/products/connect/concepts/.pages new file mode 100644 index 000000000..fc2b4576c --- /dev/null +++ b/products/connect/concepts/.pages @@ -0,0 +1,3 @@ +title: Concepts +nav: +- 'Routes': routes.md \ No newline at end of file diff --git a/build/transfers/connect/routes.md b/products/connect/concepts/routes.md similarity index 91% rename from build/transfers/connect/routes.md rename to products/connect/concepts/routes.md index 02e8b64a0..ef3139d16 100644 --- a/build/transfers/connect/routes.md +++ b/products/connect/concepts/routes.md @@ -6,11 +6,11 @@ categories: Connect, Transfer ## Routes Overview {: #routes-overview} -This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/build/transfers/connect/configuration/){target=\_blank}. +This page explains the concept of routes in Wormhole Connect. To configure routes for your widget, check the [Wormhole Connect Configuration](/docs/products/connect/configuration/data/){target=\_blank}. Routes are methods by which the widget will transfer the assets. Wormhole Connect supports Token Bridge transfers for any arbitrary token, and for specific tokens, it also supports more advanced transfer methods that provide superior UX. -When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/build/transfers/connect/features/){target=\_blank} to see under which exact conditions the routes appear. +When you select the source chain, source token, and destination chain, Wormhole Connect will display the best routes available for that particular combination. In practice, if routes other than the Token Bridge are available, only those will be displayed. Check the [feature matrix](/docs/products/connect/reference/support-matrix/){target=\_blank} to see under which exact conditions the routes appear. ## Token Bridge Routes {: #token-bridge-routes} @@ -40,7 +40,7 @@ Trustless relayers can execute the second transaction on the user's behalf. Ther ## Native Token Transfers (NTT) Routes {: #native-token-transfers-ntt-routes} -[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/build/transfers/connect/configuration/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. +[Wormhole's Native Token Transfer (NTT) framework](https://github.com/wormhole-foundation/native-token-transfers/){target=\_blank} enables token issuers to retain full ownership of their tokens across any number of chains, unlike the Token Bridge. The token issuer must deploy NTT contracts, and Wormhole Connect needs to be [configured](/docs/products/connect/configuration/data/){target=\_blank} with the appropriate `nttGroups` before such tokens are recognized as transferrable via NTT. Refer to the [documentation in the NTT repository](https://github.com/wormhole-foundation/native-token-transfers?tab=readme-ov-file#overview){target=\_blank} for more information about the contracts needed and the framework in general. #### Manual Route {: #manual-route-ntt} diff --git a/products/connect/configuration/.pages b/products/connect/configuration/.pages new file mode 100644 index 000000000..d0fb8bdcd --- /dev/null +++ b/products/connect/configuration/.pages @@ -0,0 +1,4 @@ +title: Configuration +nav: +- 'Data': data.md +- 'Theme': theme.md \ No newline at end of file diff --git a/build/transfers/connect/configuration-v0.md b/products/connect/configuration/configuration-v0.md similarity index 93% rename from build/transfers/connect/configuration-v0.md rename to products/connect/configuration/configuration-v0.md index fbf5bac95..01252978c 100644 --- a/build/transfers/connect/configuration-v0.md +++ b/products/connect/configuration/configuration-v0.md @@ -12,7 +12,7 @@ Wormhole Connect is a flexible React widget that streamlines cross-chain asset t This guide provides detailed instructions on configuring Wormhole Connect and highlights the many ways it can be customized to fit your specific needs, from integrating supported blockchains and tokens to tailoring the user interface. !!! note - For documentation on the latest version of Connect, please refer to the current [configuration documentation](/docs/build/transfers/connect/configuration/){target=\_blank}. If you are looking to upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/build/transfers/connect/upgrade/){target=\_blank} for detailed instructions. + For documentation on the latest version of Connect, please refer to the current [configuration documentation](/docs/products/connect/configuration/data/){target=\_blank}. If you are looking to upgrade from Wormhole Connect v0 to v1, please refer to the [migration guide](/docs/products/connect/guides/upgrade/){target=\_blank} for detailed instructions. ## Get Started @@ -21,13 +21,13 @@ Configure the Wormhole Connect React component by passing a `WormholeConnectConf === "React" ```ts - --8<-- 'code/build/transfers/connect/configuration/configure-react-v0.tsx' + --8<-- 'code/products/connect/configuration/configuration-v0/configure-react-v0.tsx' ``` === "HTML Tags" ```html - --8<-- 'code/build/transfers/connect/configuration/configure-html.html' + --8<-- 'code/products/connect/configuration/configuration-v0/configure-html.html' ``` ## Examples {: #examples } @@ -36,7 +36,7 @@ Below are some examples of different ways you can configure Connect. See `Wormho ??? code "View `WormholeConnectConfig`" ```ts - --8<-- 'code/build/transfers/connect/configuration/index.ts' + --8<-- 'code/products/connect/configuration/configuration-v0/index.ts' ``` ### Custom Networks and RPC Endpoints {: #custom-networks-and-rpc-endpoints } @@ -46,13 +46,13 @@ Specify supported networks, tokens, and custom RPC endpoints. Your users may enc === "Mainnet" ```js - --8<-- 'code/build/transfers/connect/configuration/custom-simple-v0.jsx' + --8<-- 'code/products/connect/configuration/configuration-v0/custom-simple-v0.jsx' ``` === "Testnet" ```js - --8<-- 'code/build/transfers/connect/configuration/custom-simple-testnet-v0.tsx' + --8<-- 'code/products/connect/configuration/configuration-v0/custom-simple-testnet-v0.tsx' ``` !!! note @@ -63,7 +63,7 @@ Specify supported networks, tokens, and custom RPC endpoints. Your users may enc Wormhole Connect offers a high level of customizability that suits and integrates with your application's design, including various options for buttons, backgrounds, popovers, fonts, and more. The following example demonstrates a variety of appearance customizations. Remember, if you prefer a visual to aid in designing your widget, you can use the [no code style interface](https://connect-in-style.wormhole.com/){target=\_blank}. ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-full.jsx' +--8<-- 'code/products/connect/configuration/configuration-v0/custom-full.jsx' ``` ### Environment {: #environment } @@ -109,7 +109,7 @@ This example configuration limits Connect to the Solana and Ethereum networks an See [`src/config/types.ts`](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. ```json ---8<-- 'code/build/transfers/connect/configuration/arbitrary-token.tsx' +--8<-- 'code/products/connect/configuration/configuration-v0/arbitrary-token.tsx' ``` ## More Configuration Options {: #more-configuration-options } @@ -214,7 +214,7 @@ By setting the `showHamburgerMenu` option to `false,` you can add extra links. T #### Sample Configuration {: #sample-configuration } ```json ---8<-- 'code/build/transfers/connect/configuration/sample-configuration.json' +--8<-- 'code/products/connect/configuration/configuration-v0/sample-configuration.json' ``` ### CoinGecko API Key {: #coingecko-api-key } @@ -240,7 +240,7 @@ Specify a set of extra networks to be displayed on the network selection modal, ??? code "View full configuration" ```json - --8<-- 'code/build/transfers/connect/configuration/advanced-configuration.json' + --8<-- 'code/products/connect/configuration/configuration-v0/advanced-configuration.json' ``` ### More Tokens {: #more-tokens } diff --git a/build/transfers/connect/configuration/configure-data.md b/products/connect/configuration/data.md similarity index 75% rename from build/transfers/connect/configuration/configure-data.md rename to products/connect/configuration/data.md index a69b739a5..736c5ead9 100644 --- a/build/transfers/connect/configuration/configure-data.md +++ b/products/connect/configuration/data.md @@ -15,13 +15,13 @@ Configure Wormhole Connect by passing a `WormholeConnectConfig` object as the `c === "React integration" ```ts - --8<-- 'code/build/transfers/connect/configuration/configure-react-v1.tsx' + --8<-- 'code/products/connect/configuration/data/configure-react-v1.tsx' ``` === "Hosted integration" ```ts - --8<-- 'code/build/transfers/connect/configuration/configure-hosted.tsx' + --8<-- 'code/products/connect/configuration/data/configure-hosted.tsx' ``` !!! note @@ -36,13 +36,13 @@ Connect lets you customize the available chains to match your project's needs. Y === "Mainnet" ```js - --8<-- 'code/build/transfers/connect/configuration/custom-simple-v1.jsx' + --8<-- 'code/products/connect/configuration/data/custom-simple-v1.jsx' ``` === "Testnet" ```js - --8<-- 'code/build/transfers/connect/configuration/custom-simple-testnet-v1.jsx' + --8<-- 'code/products/connect/configuration/data/custom-simple-testnet-v1.jsx' ``` !!! note @@ -56,18 +56,18 @@ By default, Connect offers two bridging protocols: Token Bridge (for Wormhole-wr The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: -- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank} - manually redeemed Wormhole Token Bridge route -- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank} - automatically redeemed (relayed) Token Bridge route -- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank} - manually redeemed CCTP route -- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank} - automatically redeemed (relayed) CCTP route -- **`DEFAULT_ROUTES`** - array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`) -- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank} - function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route -- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}- function that returns the manually-redeemed NTT route -- **`nttRoutes(nttConfig)`** - function that returns both NTT routes as an array -- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank} - route that offers multiple Mayan protocols -- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank} - route for Mayan's Swift protocol only -- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank} - route for Mayan's MCTP protocol only -- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank} - route for Mayan's original Wormhole transfer protocol +- [**`TokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/manual.ts){target=\_blank}: Manually redeemed Wormhole Token Bridge route. +- [**`AutomaticTokenBridgeRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/tokenBridge/automatic.ts){target=\_blank}: Automatically redeemed (relayed) Token Bridge route. +- [**`CCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/manual.ts){target=\_blank}: Manually redeemed CCTP route. +- [**`AutomaticCCTPRoute`**](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/connect/src/routes/cctp/automatic.ts){target=\_blank}: Automatically redeemed (relayed) CCTP route. +- **`DEFAULT_ROUTES`**: Array containing the four preceding routes (`TokenBridgeRoute`, `AutomaticTokenBridgeRoute`, `CCTPRoute`, `AutomaticCCTPRoute`). +- [**`nttAutomaticRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/automatic.ts){target=\_blank}: Function that returns the automatically-redeemed (relayed) Native Token Transfer (NTT) route. +- [**`nttManualRoute(nttConfig)`**](https://github.com/wormhole-foundation/native-token-transfers/blob/main/sdk/route/src/manual.ts){target=\_blank}: Function that returns the manually-redeemed NTT route. +- **`nttRoutes(nttConfig)`**: Function that returns both NTT routes as an array. +- [**`MayanRoute`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L57){target=\_blank}: Route that offers multiple Mayan protocols. +- [**`MayanRouteSWIFT`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L528){target=\_blank}: Route for Mayan's Swift protocol only. +- [**`MayanRouteMCTP`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L539){target=\_blank}: Route for Mayan's MCTP protocol only. +- [**`MayanRouteWH`**](https://github.com/mayan-finance/wormhole-sdk-route/blob/main/src/index.ts#L550){target=\_blank}: Route for Mayan's original Wormhole transfer protocol. In addition to these routes, developers can create custom routes for their Wormhole-based protocols. For examples, refer to the [NTT](https://github.com/wormhole-foundation/native-token-transfers/tree/main/sdk/route){target=\_blank} and the [Mayan](https://github.com/mayan-finance/wormhole-sdk-route){target=\_blank} example GitHub repositories. @@ -78,15 +78,15 @@ For further details on the `route` plugin interface, refer to the [Wormhole Type To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: ```typescript ---8<-- 'code/build/transfers/connect/configuration/example-cctp.ts' +--8<-- 'code/products/connect/configuration/data/example-cctp.ts' ``` #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge and CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript ---8<-- 'code/build/transfers/connect/configuration/example-all-routes.ts' +--8<-- 'code/products/connect/configuration/data/example-all-routes.ts' ``` This flexible plugin allows you to combine default routes (such as Token Bridge and CCTP) with third-party protocols, offering complete control over which routes are available in your application. @@ -103,7 +103,7 @@ This example configuration adds the BONK token to Connect. Note the `wrappedToke See the [Connect source code](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/types.ts){target=\_blank} for the type definition of `TokensConfig`. ```typescript ---8<-- 'code/build/transfers/connect/configuration/add-token.tsx' +--8<-- 'code/products/connect/configuration/data/add-token.tsx' ``` ### Whitelisting Tokens {: #whitelisting-tokens } @@ -116,13 +116,13 @@ Connect offers a list of built-in tokens by default. You can see it below: You can customize the tokens shown in the UI using the `tokens` property. The following example adds a custom token and limits Connect to showing only that token, along with the native gas tokens ETH and SOL. ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-tokens-whitelist.jsx' +--8<-- 'code/products/connect/configuration/data/custom-tokens-whitelist.jsx' ``` You can whitelist tokens by symbol or by specifying tuples of [chain, address]. For example, this would show only BONK token (on all chains you've whitelisted) as well as [`EPjFW...TDt1v`](https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v){target=\_blank} on Solana, which is USDC. ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-tokens-whitelist-advanced.jsx' +--8<-- 'code/products/connect/configuration/data/custom-tokens-whitelist-advanced.jsx' ``` ### User-Inputted Tokens {: #user-inputted-tokens } @@ -132,7 +132,7 @@ As of version 2.0, Connect allows users to paste token addresses to bridge any t If you provide a token whitelist (see above), this is turned off automatically. However, you can also disable it explicitly like this: ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-disable-arbitrary-tokens.jsx' +--8<-- 'code/products/connect/configuration/data/custom-disable-arbitrary-tokens.jsx' ``` Setting `ui.disableUserInputtedTokens` to `true` will disable the ability to paste in token addresses. @@ -142,7 +142,7 @@ Setting `ui.disableUserInputtedTokens` to `true` will disable the ability to pas Landing transactions on Solana can require finely tuned priority fees when there is congestion. You can tweak how Connect determines these with `transactionSettings`. All of the parameters in this configuration are optional; you can provide any combination of them. ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-tx-settings-solana.jsx' +--8<-- 'code/products/connect/configuration/data/custom-tx-settings-solana.jsx' ``` !!! note @@ -157,12 +157,4 @@ Your selected blockchain network determines the available wallet options when us The wallet options automatically adjust based on the selected chain, providing a seamless user experience without additional configuration. -If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. - -### CoinGecko API Key {: #coingecko-api-key } - -The CoinGecko API can be used to fetch token price data. If you have a [CoinGecko API Plan](https://apiguide.coingecko.com/getting-started/getting-started){target=\_blank}, you can include the API key in the configuration. - -```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-coingecko-key.jsx' -``` +If you would like to offer Reown Cloud (formerly WalletConnect) as a supported wallet option, you'll need to obtain a project ID on the [Reown Cloud dashboard](https://cloud.reown.com/){target=\_blank}. \ No newline at end of file diff --git a/build/transfers/connect/configuration/configure-theme.md b/products/connect/configuration/theme.md similarity index 85% rename from build/transfers/connect/configuration/configure-theme.md rename to products/connect/configuration/theme.md index a513f6c73..d41479d5b 100644 --- a/build/transfers/connect/configuration/configure-theme.md +++ b/products/connect/configuration/theme.md @@ -6,7 +6,7 @@ categories: Connect, Transfer ## Theme & UI Customization -This page focuses on how to style the Wormhole Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. +This page focuses on how to style the Connect widget, covering color schemes, fonts, layout changes (like toggling the hamburger menu), and adding extra menu entries. You'll learn how to customize Connect's look and feel to match your application's branding. ### Changing the Color Scheme @@ -15,13 +15,13 @@ You can customize Connect's color scheme by providing a `theme` prop. === "React integration" ```ts - --8<-- 'code/build/transfers/connect/configuration/custom-colors.tsx' + --8<-- 'code/products/connect/configuration/theme/custom-colors.tsx' ``` === "Hosted integration" ```ts - --8<-- 'code/build/transfers/connect/configuration/custom-colors-hosted.tsx' + --8<-- 'code/products/connect/configuration/theme/custom-colors-hosted.tsx' ``` The `WormholeConnectTheme` type supports the following properties: @@ -54,5 +54,5 @@ By setting the `showHamburgerMenu` option to `false,` you can add extra links. T | `order` | Order where the new item should be injected | ```jsx ---8<-- 'code/build/transfers/connect/configuration/custom-menu.jsx' +--8<-- 'code/products/connect/configuration/theme/custom-menu.jsx' ``` diff --git a/build/transfers/connect/faqs.md b/products/connect/faqs.md similarity index 92% rename from build/transfers/connect/faqs.md rename to products/connect/faqs.md index f7eb7ff28..d4c9a4cfa 100644 --- a/build/transfers/connect/faqs.md +++ b/products/connect/faqs.md @@ -8,7 +8,7 @@ categories: Connect, Transfer ## What types of assets does Connect support? -Wormhole Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: +Connect supports both native and wrapped assets across all Wormhole-supported blockchains. This includes: - Major stablecoins like USDT and USDC (via CCTP) - Native gas tokens such as ETH, SOL, etc. @@ -24,7 +24,7 @@ Connect supports around 30 chains, spanning various blockchain runtimes: - Solana - Move-based chains (Sui, Aptos) -For a complete list of supported chains, see the [Connect-supported chains list](/docs/build/transfers/connect/features/){target=\_blank}. +For a complete list of supported chains, see the [Connect-supported chains list](/docs/products/connect/reference/support-matrix/){target=\_blank}. ## What is gas dropoff? @@ -38,9 +38,9 @@ Connect can be [fully customized](https://connect-in-style.wormhole.com/){target Connect relies on the NTT SDK for integration, with platform-specific implementations for Solana and EVM. The critical methods involved include initiate and redeem functions and rate capacity methods. These functions ensure Connect can handle token transfers and manage chain-rate limits. -## Do integrators need to enable wallets like Phantom or Backpack in Wormhole Connect? +## Do integrators need to enable wallets like Phantom or Backpack in Connect? -Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Wormhole Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. +Integrators don’t need to explicitly enable wallets like Phantom or Backpack in Connect. However, the wallet must be installed and enabled in the user's browser to appear as an option in the interface. ## Which function should be modified to set priority fees for Solana transactions? diff --git a/products/connect/get-started.md b/products/connect/get-started.md new file mode 100644 index 000000000..5425f5d27 --- /dev/null +++ b/products/connect/get-started.md @@ -0,0 +1,86 @@ +--- +title: Get Started with Connect +description: Follow this guide to configure and use the Connect UI widget to easily add an intuitive, multichain asset transfer UI to your web applications. +categories: Connect, Transfer +--- + +# Get Started with Connect + +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} + +## Introduction + +Connect helps you to easily add an intuitive, multichain asset transfer UI to your web applications. The guide demonstrates how to configure the Connect widget, add it to a React application, and view it locally. + +## Install Connect + +To install the [Wormhole Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: + +```bash +npm i @wormhole-foundation/wormhole-connect +``` + +## Prerequisites + +Before you begin, make sure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + +- (Optional) To test a transfer from your demo app, you'll need: + + - A wallet with [Sui testnet tokens](https://faucet.sui.io/){target=\_blank} + - A wallet with an Avalanche Fuji address (to use as the recipient; no tokens required) + +## Install and Set Up Project + +1. Clone the demo repository and navigate to the project directory: + + ```bash + git clone https://github.com/wormhole-foundation/demo-basic-connect.git + cd demo-basic-connect + ``` + +2. Install the dependencies: + + ```bash + npm install + ``` + +3. Start the application: + + ```bash + npm start + ``` + +4. Open your browser to [localhost:3000](http://localhost:3000){target=\_blank} to view the application locally. It will look similar to the following: + + ![Deployed Connect Widget](/docs/images/products/connect/tutorials/react-dapp/get-started/connect-get-started-01.webp) + +## Configure Connect + +Open the `App.tsx` file in your code editor of choice. You will see code similar to the following: + +```typescript title="App.tsx" +--8<-- 'code/products/connect/configuration/get-started/App.tsx' +``` + +The preceding sample code configures Connect by setting values inside `config` and `theme` as follows: + +- **Defines the network**: Options include `Mainnet`, `Testnet`, or `Devnet`. +- **Defines chains to include**: This example uses Sui and Avalanche. See the complete list of [Connect-supported chain names](https://github.com/wormhole-foundation/wormhole-sdk-ts/blob/main/core/base/src/constants/chains.ts){target=\_blank} if you would like to use different chains. +- **Adds a title to UI**: (Optional) If defined, it will render above the widget in the UI. +- **Defines the theme**: This example sets the mode to `dark` and adds a primary color. + +## Interact with Connect + +Congratulations! You've successfully used Connect to create a simple multichain token transfer application. You can now follow the prompts in the UI to connect your developer wallets and send a test transfer. + +## Next Steps + +Use the following guides to configure your Connect instance and integrate it into your application: + +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. +- **[Integrate Connect into a React DApp](/docs/products/connect/tutorials/react-dapp/)**: Learn how to integrate Connect into a React application, including setting up the widget and handling transfers. + + diff --git a/products/connect/guides/.pages b/products/connect/guides/.pages new file mode 100644 index 000000000..b94115f68 --- /dev/null +++ b/products/connect/guides/.pages @@ -0,0 +1,4 @@ +title: Guides +nav: +- 'Integrate via CDN': hosted-version.md +- 'Migration to v1': upgrade.md \ No newline at end of file diff --git a/products/connect/guides/hosted-version.md b/products/connect/guides/hosted-version.md new file mode 100644 index 000000000..e106271a8 --- /dev/null +++ b/products/connect/guides/hosted-version.md @@ -0,0 +1,42 @@ +--- +title: Integrate Connect via CDN +description: +categories: Connect, Transfer +--- + +# Integrate Connect via CDN + +[Wormhole Connect](/docs/products/connect/overview/){target=\_blank} is a prebuilt UI component that makes it easy to transfer tokens across chains. You can integrate it into any website using either React or a hosted version served via [jsDelivr](https://www.jsdelivr.com/){target=\_blank}. + +This guide focuses on using the hosted version—ideal for simpler setups or non-React environments. It includes everything you need to get started with just a few lines of code. + +If you're using React, refer to the [Get Started with Connect](/docs/products/connect/get-started/){target=\_blank} guide. + +## Install Connect + +To install the [Connect npm package](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect){target=\_blank}, run the following command: + +```bash +npm i @wormhole-foundation/wormhole-connect +``` + +## Add Connect to Your Project Using the Hosted Version + +The hosted version uses pre-built packages (including React) served via jsDelivr from npm. To integrate it without using React directly, add the following to your JavaScript project: + +```js +--8<-- 'code/products/connect/guides/hosted-version/hosted-1.js' +``` + +You can provide config and theme parameters in a second function argument: + +```js +--8<-- 'code/products/connect/guides/hosted-version/hosted-2.js' +``` + +## Next Steps + +Use the following guides to configure your Connect instance: + +- **[Data Configuration](/docs/products/connect/configuration/data/)**: Learn how to specify custom networks and RPC endpoints, integrate different bridging protocols, add new tokens, and more. +- **[Theme Configuration](/docs/products/connect/configuration/theme/)**: Learn how to customize Connect's look and feel to match your application's branding. diff --git a/build/transfers/connect/upgrade.md b/products/connect/guides/upgrade.md similarity index 87% rename from build/transfers/connect/upgrade.md rename to products/connect/guides/upgrade.md index 62a76ced3..11ede36c8 100644 --- a/build/transfers/connect/upgrade.md +++ b/products/connect/guides/upgrade.md @@ -18,11 +18,9 @@ This guide will help you migrate to the new version in just a few simple steps. These updates ensure better performance and a smoother integration experience. -For complete documentation on the previous version of Wormhole Connect, please refer to the [Wormhole Connect guide](/docs/build/transfers/connect/){target=\_blank}. - ## Update the Connect Package -To begin the migration process, update the Wormhole Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. +To begin the migration process, update the Connect [**npm package**](https://www.npmjs.com/package/@wormhole-foundation/wormhole-connect/v/1.0.0-beta.6-development?activeTab=readme){target=\_blank} to the latest version 1.0. Updating to the latest version provides access to the newest features and improvements, including the modernized design and enhanced routing capabilities. Run the following command in your terminal: @@ -125,12 +123,12 @@ The `networks` property, which allowed whitelisting chains, is now renamed `chai ### Update `routes` to Use Route Plugins -The `routes` property in Wormhole Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. +The `routes` property in Connect version 1.0 has significantly improved. Previously, `routes` was a simple array of strings. The latest version has been transformed into a flexible plugin system, allowing you to include specific routes for various protocols. -By default, if no `routes` property is set, Wormhole Connect will provide routes for two core protocols: +By default, if no `routes` property is set, Connect will provide routes for two core protocols: - - [Wormhole Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} - - [CCTP](/docs/learn/transfers/cctp/){target=\_blank} + - [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} + - [CCTP](/docs/products/cctp-bridge/overview/){target=\_blank} For most use cases, integrators require more than the default routes. The new `routes` property allows you to specify which protocols to include and exclude any routes unnecessary for your application, including both default and third-party routes. @@ -139,7 +137,7 @@ For most use cases, integrators require more than the default routes. The new `r The `@wormhole-foundation/wormhole-connect` package offers a variety of `route` plugins to give you flexibility in handling different protocols. You can choose from the following `route` exports for your integration: ???- tip "`route` Plugins" - - **`TokenBridgeRoute`** - manually redeemed Wormhole Token Bridge route + - **`TokenBridgeRoute`** - manually redeemed Token Bridge route - **`AutomaticTokenBridgeRoute`** - automatically redeemed (relayed) Token Bridge route - **`CCTPRoute`** - manually redeemed CCTP route - **`AutomaticCCTPRoute`** - automatically redeemed (relayed) CCTP route @@ -160,7 +158,7 @@ Now that you know the available `route` plugins, let's explore some examples of #### Example: Offer Only CCTP Transfers -To configure Wormhole Connect to offer only USDC transfers via the CCTP route, use the following configuration: +To configure Connect to offer only USDC transfers via the CCTP route, use the following configuration: ```typescript import WormholeConnect, { @@ -177,7 +175,7 @@ const config: WormholeConnectConfig = { #### Example: Offer All Default Routes and Third-Party Plugins -In this example, Wormhole Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/build/transfers/native-token-transfers/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. +In this example, Connect is configured with routes for both default protocols (Token Bridge & CCTP), as well as third-party protocols like [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} and [Mayan Swap](https://swap.mayan.finance/){target=\_blank}. ```typescript import WormholeConnect, { @@ -200,7 +198,7 @@ This flexible plugin allows you to combine default routes (such as Token Bridge ### Update the `tokensConfig` Structure -In Wormhole Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. +In Connect version 1.0, the `tokensConfig` property has been updated to simplify the structure and improve flexibility for token handling across chains. The previous configuration has been streamlined, and a new key, `wrappedTokens,` has been introduced to handle foreign assets more effectively. Key Changes to `tokensConfig`: @@ -277,7 +275,7 @@ Key Changes to `tokensConfig`: ### Update NTT Configuration -In Wormhole Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. +In Connect version 1.0, the `nttGroups` property, which was used to configure Native Token Transfers (NTT), has been removed. Instead, the NTT configuration is passed directly to the NTT route constructor. This update simplifies the setup and provides more flexibility for defining NTT routes. Key changes: @@ -376,7 +374,7 @@ This change simplifies the configuration process by providing a cleaner, more fl ### Update UI Configuration -In Wormhole Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. +In Connect version 1.0, the user interface configuration has been significantly updated. Several previously scattered UI properties have now been consolidated under a new `ui` key, making the UI configuration cleaner and easier to manage. Key UI changes: @@ -500,7 +498,7 @@ Important details: ### Removed Configuration Properties -Several configuration properties have been removed in Wormhole Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. +Several configuration properties have been removed in Connect version 1.0. These keys no longer have any effect, and providing values for them in the configuration will not result in any changes. Removed config keys: @@ -528,7 +526,7 @@ For those using the CDN-hosted version of Wormhole Connect, the package's instal npm install @wormhole-foundation/wormhole-connect@^1.0 ``` -2. After installing the package, you can embed Wormhole Connect into your page by adding the following code: +2. After installing the package, you can embed Connect into your page by adding the following code: ```typescript import { wormholeConnectHosted } from '@wormhole-foundation/wormhole-connect'; diff --git a/products/connect/overview.md b/products/connect/overview.md new file mode 100644 index 000000000..88008006f --- /dev/null +++ b/products/connect/overview.md @@ -0,0 +1,62 @@ +--- +title: Wormhole Connect +description: With Wormhole Connect, you can seamlessly bridge digital assets and data across a wide range of supported blockchain networks. +categories: Connect, Transfer +--- + +# Connect Overview + +With the Wormhole Connect widget, you can enable users to perform multichain asset transfers directly within your application. Connect simplifies the complexity of bridging, offering a single, intuitive point of interaction for moving assets across diverse blockchains. This empowers you to access liquidity and opportunities across any connected network seamlessly. + +## Key Features + +Connect's notable features include: + +- **In-app multichain transfers**: Bridge assets without leaving your app. +- **Customizable features**: Specify chains and custom RPCs, manage tokens, and select bridging [routes](/docs/products/connect/concepts/routes/){target=\_blank} such as Token Bridge, CCTP, or NTT. +- **Customizable UI**: Style the bridge interface to match your brand. +- **Optional destination gas**: Provide gas for initial transactions on the target chain. +- **Wrapped and native assets support**: Supports both wrapped and native tokens and integrates with Settlement. + +Be sure to check the [Feature Support Matrix](/docs/products/connect/reference/support-matrix/#feature-support-matrix){target=\_blank} to find out which routes and features are supported for each chain. + +## How It Works + +When a user initiates a multichain transfer, Connect walks them through key steps and automates the transfer process behind the scenes, including: + +1. **Initiating the transfer**: Connect your chosen wallet to the source chain, select asset and source chain for the transfer. +2. **Finalize transfer setup**: Connect the destination wallet, select the target chain and select a bridging route (manual or automatic). +3. **Transaction submission on source chain**: Confirms the transfer details to trigger the asset lock or deposit on the initial blockchain. Connect will guide you through the transaction process. +4. **VAA or attestation creation**: Wormhole [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the source transaction and produce a [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}. +5. **Relaying to destination**: The VAA or attestation is automatically relayed to the destination chain. +6. **Verification on destination**: Contracts on the target chain receive and verify the incoming VAA. +7. **Asset release/minting**: Upon successful verification, the equivalent assets are either released or minted on the target chain and delivered to your wallet. + +!!! tip + If you want more hands on experience with Connect, checkout [Portal Bridge](https://portalbridge.com/){target=\_blank}. + +## Use Cases + +Here are some key use cases that highlight the power and versatility of Connect: + +- **Cross-Chain Swaps and Liquidity Aggregation** + + - [**Connect**](/docs/products/connect/get-started/): Handles user-friendly asset transfers. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Moves native assets across chains. + - [**Queries**](/docs/products/queries/overview/): Fetches real-time prices for optimal trade execution. + +- **Cross-Chain Payment Widgets** + + - [**Connect**](/docs/products/connect/get-started/): Facilitates seamless payments in various tokens. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/): Ensures direct, native asset transfers. + +- **Web3 Game Asset Transfers** + + - [**Connect**](/docs/products/connect/get-started/): Provide a user-friendly way to move game tokens across chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/): Handle the underlying lock-and-mint logic securely. + +## Next Steps + +Add Connect to your app with these key setup steps: + +[timeline(wormhole-docs/.snippets/text/products/connect/overview/connect-timeline.json)] diff --git a/products/connect/reference/.pages b/products/connect/reference/.pages new file mode 100644 index 000000000..1786952e3 --- /dev/null +++ b/products/connect/reference/.pages @@ -0,0 +1,3 @@ +title: Reference +nav: +- 'Support Matrix': support-matrix.md diff --git a/build/transfers/connect/features.md b/products/connect/reference/support-matrix.md similarity index 97% rename from build/transfers/connect/features.md rename to products/connect/reference/support-matrix.md index 23277e078..329f04d58 100644 --- a/build/transfers/connect/features.md +++ b/products/connect/reference/support-matrix.md @@ -43,7 +43,7 @@ This route appears if both of the following conditions are satisfied: ### Token Bridge Relayer {: #token-bridge-relayer} -On the [routes](/docs/build/transfers/connect/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. +On the [routes](/docs/products/connect/concepts/routes/){target=\_blank} page, this is referred to as the automatic route in the Token Bridge section. Trustless relayers can execute the second transaction on behalf of the user, so the user only needs to perform one transaction on the origin chain to have the tokens delivered to the destination automatically—for a small fee. diff --git a/products/connect/tutorials/.pages b/products/connect/tutorials/.pages new file mode 100644 index 000000000..3d599f5b0 --- /dev/null +++ b/products/connect/tutorials/.pages @@ -0,0 +1,4 @@ +title: Tutorials +nav: +- 'Create a React Bridging App': 'react-dapp.md' + diff --git a/products/connect/tutorials/react-dapp.md b/products/connect/tutorials/react-dapp.md new file mode 100644 index 000000000..ae659a0ed --- /dev/null +++ b/products/connect/tutorials/react-dapp.md @@ -0,0 +1,147 @@ +--- +title: Integrate Connect into a React DApp Tutorial +description: Learn how to use Wormhole Connect to transfers tokens cross-chain seamlessly between Sui and Avalanche Fuji with this step-by-step guide. +categories: Connect, Transfer +--- + +# Integrate Connect into a React DApp + +:simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank} + +## Introduction + +In this tutorial, we'll explore how to integrate [Wormhole Connect](/docs/products/connect/overview/){target=\_blank} to enable cross-chain token transfers and interactions. Connect offers a simplified interface for developers to facilitate seamless token transfers between blockchains. Using Connect, you can easily bridge assets across multiple ecosystems without diving into the complex mechanics of cross-chain communication. + +While this tutorial will guide you through the process using a specific blockchain as an example, the principles and steps outlined here can be applied to any [blockchain supported by Wormhole](/docs/products/connect/reference/support-matrix/){target=\_blank}. In this example, we'll work with Sui as our source blockchain and Avalanche Fuji as the destination blockchain. + +## Prerequisites + +To get started with Connect, we'll first need to set up a basic environment that allows for cross-chain token transfers. +Before starting this tutorial, ensure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- A [Sui wallet](https://suiwallet.com/){target=\_blank} set up and ready for use +- A [compatible wallet](https://support.avax.network/en/articles/5520938-what-are-the-official-avalanche-wallets){target=\_blank} for Avalanche Fuji, such as [MetaMask](https://metamask.io/){target=\_blank} +- Testnet tokens for [Sui](https://docs.sui.io/guides/developer/getting-started/get-coins){target=\_blank} and [Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} to cover gas fees + +## Set Up Connect for Sui Transfers + +### Create a React Project + +In this tutorial, we'll use [Next.js](https://nextjs.org/docs/app/getting-started){target=\_blank}, a popular framework built on top of React, to set up your app: + +1. Open your terminal and run the following command to create a new React app: + + ```bash + npx create-next-app@latest connect-tutorial + ``` + + We recommend enabling TypeScript and creating a `src/` directory during setup. Other options can be configured based on your preferences. + +2. Navigate into the project directory: + + ```bash + cd connect-tutorial + ``` + + +### Install Connect + +Next, install the Connect package as a dependency by running the following command inside your project directory: + +```bash +npm install @wormhole-foundation/wormhole-connect +``` + +### Integrate Connect into the Application + +Now, we need to modify the default `page.tsx` file to integrate Connect. We are going to use [version V1.0](/docs/products/connect/guides/upgrade/){target=\_blank} or later, make sure to check which version of Connect you are using. Open `src/app/page.tsx` and replace the content with the following code: + +=== "JavaScript" + + ```js + --8<-- "code/products/connect/tutorials/react-dapp/snippet-1.js" + ``` + +=== "TypeScript" + + ```ts + --8<-- "code/products/connect/tutorials/react-dapp/snippet-2.ts" + ``` + +- Set `network` to `'Testnet'` - this ensures that Connect uses the testnet environment +- Set `chains` to `['Sui', 'Avalanche']` - configures the app to allow transfers between Sui and Avalanche Fuji, the testnet for Avalanche + +### Customize Connect + +To further customize Connect for your application, such as adjusting the UI, adding custom tokens, or configuring specific chain settings, you can refer to the [Connect Configuration guide](/docs/products/connect/configuration/data/){target=\_blank}. + +### Run the Application + +Make sure you're in the root directory of your React app, and run the following command to start the application: + +```bash +npm run dev +``` + +Now your React app should be up and running, and Connect should be visible on `http://localhost:3000/`. You should see the Connect component, which will include a UI for selecting networks and tokens for cross-chain transfers. + +## Transfer Tokens from Sui to Fuji + +Before transferring token ensure you have enough testnet SUI and Fuji tokens to cover the gas fees for the transfer. + +To transfer tokens from Sui to Fuji in the Connect interface: + +1. Select **Sui** as the source network, connect your Sui wallet, and choose **SUI** as the asset you wish to transfer +2. Choose **Fuji** as the destination network and connect your wallet with the Fuji network +3. Enter the amount of SUI tokens you wish to transfer + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-1.webp){.half} + +4. Choose to view other routes + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-2.webp){.half} + +5. Select the manual bridge option, which will require two transactions: one on the source chain (Sui) and one on the destination chain (Fuji) + + !!! note + It is recommended to use the manual bridge option for this tutorial. The automatic bridge feature is currently undergoing improvements, while the manual bridge ensures that transfers complete successfully. + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-3.webp){.half} + +6. Review and confirm the transfer on Sui. This will lock your tokens on the Sui chain + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-4.webp){.half} + +7. Follow the on-screen prompts to approve the transaction. You will be asked to sign with your Sui wallet + + ![](/docs/images/products/connect/tutorials/react-dapp/connect-5.webp){.half} + +Once the transaction has been submitted, Connect will display the progress of the transfer. Monitor the status until you're prompted to complete the transaction on the destination chain. You can also track your transactions on [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. + +## Claim Tokens on Fuji + +After the Sui transaction is complete, confirm the final transaction on Fuji by claiming the wrapped tokens. You will be asked to confirm the transaction with your Fuji wallet. + +![](/docs/images/products/connect/tutorials/react-dapp/connect-6.webp){.half} + +Once confirmed, check your Fuji wallet to verify that the wrapped SUI tokens have been successfully received. + +![](/docs/images/products/connect/tutorials/react-dapp/connect-7.webp){.half} + +## Resources + +If you'd like to explore the complete project or need a reference while following this tutorial, you can find the entire codebase in the [Sui-Connect GitHub repository](https://github.com/wormhole-foundation/demo-basic-connect){target=\_blank}. The repository includes an integration of Connect in a React app for bridging tokens between the Sui and Fuji (Avalanche Testnet) networks. + +## Conclusion + +In this tutorial, you've gained hands-on experience with integrating Connect to enable cross-chain token transfers. You've learned to configure a React app for seamless interactions between Sui and Avalanche Fuji, providing users with the ability to bridge assets across chains with ease. + +By following these steps, you've learned how to: + +- Set up a React project tailored for cross-chain transfers +- Install and configure Connect to support multiple blockchains +- Implement a streamlined UI for selecting source and destination chains, connecting wallets, and initiating transfers +- Execute a token transfer from Sui to Avalanche Fuji, monitoring each step and confirming the transaction on both networks + +With these tools and knowledge, you're now equipped to build powerful cross-chain applications using Connect, opening up possibilities for users to move assets across ecosystems securely and efficiently. \ No newline at end of file diff --git a/products/messaging/.pages b/products/messaging/.pages new file mode 100644 index 000000000..25c295f4a --- /dev/null +++ b/products/messaging/.pages @@ -0,0 +1,6 @@ +title: Messaging +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- tutorials diff --git a/products/messaging/get-started.md b/products/messaging/get-started.md new file mode 100644 index 000000000..a6149e236 --- /dev/null +++ b/products/messaging/get-started.md @@ -0,0 +1,100 @@ +--- +title: Get Started with Messaging +description: Follow this guide to use Wormhole's core protocol to publish a multichain message and return transaction information with VAA identifiers. +categories: Basics, Typescript-SDK +--- + +# Get Started with Messaging + +Wormhole's core functionality allows you to send any data packet from one supported chain to another. This guide demonstrates how to publish your first simple, arbitrary data message from an EVM environment source chain using the Wormhole TypeScript SDK's core messaging capabilities. + +## Prerequisites + +Before you begin, ensure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed +- [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed +- [Ethers.js](https://docs.ethers.org/v6/getting-started/){target=\_blank} installed (this example uses version 6) +- A small amount of testnet tokens for gas fees. This example uses [Sepolia ETH](https://sepolia-faucet.pk910.de/){target=\_blank} but can be adapted for any supported network +- A private key for signing blockchain transactions + +## Configure Your Messaging Environment + +1. Create a directory and initialize a Node.js project: + + ```bash + mkdir core-message + cd core-message + npm init -y + ``` + +2. Install TypeScript, tsx, Node.js type definitions, and Ethers.js: + + ```bash + npm install --save-dev tsx typescript @types/node ethers + ``` + +3. Create a `tsconfig.json` file if you don't have one. You can generate a basic one using the following command: + + ```bash + npx tsc --init + ``` + + Make sure your `tsconfig.json` includes the following settings: + + ```json + { + "compilerOptions": { + // es2020 or newer + "target": "es2020", + // Use esnext if you configured your package.json with type: "module" + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } + } + ``` + +4. Install the [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}: + + ```bash + npm install @wormhole-foundation/sdk + ``` + +5. Create a new file named `main.ts`: + + ```bash + touch main.ts + ``` + +## Construct and Publish Your Message + +1. Open `main.ts` and update the code there as follows: + + ```ts title="main.ts" + --8<-- "code/products/messaging/get-started/main.ts" + ``` + + This script initializes the SDK, defines values for the source chain, creates an EVM signer, constructs the message, uses the core protocol to generate, sign, and send the transaction, and returns the VAA identifiers upon successful publication of the message. + +2. Run the script using the following command: + + ```bash + npx tsx main.ts + ``` + + You will see terminal output similar to the following: + + --8<-- "code/products/messaging/get-started/terminal01.html" + +3. Make a note of the transaction ID and VAA identifier values. You can use the transaction ID to [view the transaction on Wormholescan](https://wormholescan.io/#/tx/0xeb34f35f91c72e4e5198509071d24fd25d8a979aa93e2f168de075e3568e1508?network=Testnet){target=\_blank}. The emitter chain, emitter address, and sequence values are used to retrieve and decode signed messages + +Congratulations! You've published your first multichain message using Wormhole's TypeScript SDK and core protocol functionality. Consider the following options to build upon what you've accomplished. + +## Next Steps + +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/){target=\_blank}: Follow this guide to start working with multichain token transfers using Wormhole Token Bridge's lock and mint mechanism to send tokens across chains. +- [**Get Started with the Solidity SDK**](/docs/tools/solidity-sdk/get-started/){target=\_blank}: Smart contract developers can follow this on-chain integration guide to use Wormhole Solidity SDK-based sender and receiver contracts to send testnet USDC across chains. \ No newline at end of file diff --git a/products/messaging/guides/.pages b/products/messaging/guides/.pages new file mode 100644 index 000000000..27a4ea44e --- /dev/null +++ b/products/messaging/guides/.pages @@ -0,0 +1,4 @@ +title: Guides +nav: +- 'Interact with Wormhole Relayers': wormhole-relayers.md +- 'Interact with Core Contracts': core-contracts.md \ No newline at end of file diff --git a/build/core-messaging/core-contracts.md b/products/messaging/guides/core-contracts.md similarity index 81% rename from build/core-messaging/core-contracts.md rename to products/messaging/guides/core-contracts.md index 876940960..0ef3e6a29 100644 --- a/build/core-messaging/core-contracts.md +++ b/products/messaging/guides/core-contracts.md @@ -12,15 +12,15 @@ Wormhole's Core Contracts, deployed on each supported blockchain network, enable While the implementation details of the Core Contracts varies by network, the core functionality remains consistent across chains. Each version of the Core Contract facilitates secure and reliable cross-chain communication, ensuring that developers can effectively publish and verify messages. -This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank} page in the Learn section. +This guide will walk you through the variations and key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your cross-chain contracts. To learn more about Core Contracts' features and how it works, please refer to the [Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} page in the Learn section. ## Prerequisites To interact with the Wormhole Core Contract, you'll need the following: -- The [address of the Core Contract](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on -- The [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on -- The [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on +- The [address of the Core Contract](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on the chains you're deploying your contract on +- The [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're deploying your contract on +- The [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} (consistency) levels (required finality) for the chains you're deploying your contract on ## How to Interact with Core Contracts @@ -33,14 +33,14 @@ While the implementation details of the Core Contracts vary by network, the core ### Sending Messages -To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/learn/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/learn/transfers/token-bridge/#token-bridge){target=\_blank}. +To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/docs/products/reference/glossary/#emitter){target=\_blank}. This emitter might be your contract or an existing application such as the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. === "EVM" The `IWormhole.sol` interface provides the `publishMessage` function, which can be used to publish a message directly to the Core Contract: ```solidity - --8<-- 'code/build/core-messaging/core-contracts/sending.sol' + --8<-- 'code/products/messaging/guides/core-contracts/sending.sol' ``` ??? interface "Parameters" @@ -70,7 +70,7 @@ To send a message, regardless of the environment or chain, the Core Contract is ??? interface "Example" ```solidity - --8<-- 'code/build/core-messaging/core-contracts/sendMessageEVM.sol' + --8<-- 'code/products/messaging/guides/core-contracts/sendMessageEVM.sol' ``` View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. @@ -138,7 +138,7 @@ To send a message, regardless of the environment or chain, the Core Contract is `payload` ++"Vec"++ - The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/learn/infrastructure/vaas#payload-types){target=\_blank} page. + The data being sent in the message. This is a variable-length byte array that contains the actual content or information being transmitted. To learn about the different types of payloads, check out the [VAAs](/docs/protocol/infrastructure/vaas#payload-types){target=\_blank} page. --- @@ -164,14 +164,14 @@ To send a message, regardless of the environment or chain, the Core Contract is ??? interface "Example" ```rust - --8<-- 'code/build/core-messaging/core-contracts/sendMessageSolana.rs' + --8<-- 'code/products/messaging/guides/core-contracts/sendMessageSolana.rs' ``` View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. -Once the message is emitted from the Core Contract, the [Guardian Network](/docs/learn/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/learn/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. +Once the message is emitted from the Core Contract, the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} will observe the message and sign the digest of an Attestation [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. On EVM chains, the body of the VAA is hashed twice with keccak256 to produce the signed digest message. On Solana, the [Solana secp256k1 program](https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program){target=\_blank} will hash the message passed. In this case, the argument for the message should be a single hash of the body, not the twice-hashed body. -VAAs are [multicast](/docs/learn/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. +VAAs are [multicast](/docs/protocol/infrastructure/core-contracts/#multicast){target=\_blank} by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt. ### Receiving Messages @@ -182,7 +182,7 @@ The way a message is received and handled depends on the environment. On EVM chains, the message passed is the raw VAA encoded as binary. The `IWormhole.sol` interface provides the `parseAndVerifyVM` function, which can be used to parse and verify the received message. ```solidity - --8<-- 'code/build/core-messaging/core-contracts/receiving.sol' + --8<-- 'code/products/messaging/guides/core-contracts/receiving.sol' ``` ??? interface "Parameters" @@ -195,7 +195,7 @@ The way a message is received and handled depends on the environment. `vm` ++"VM memory"++ - The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/learn/infrastructure/vaas/) page. + The valid parsed VAA, which will include the original `emitterAddress`, `sequenceNumber`, and `consistencyLevel`, among other fields outlined on the [VAAs](/docs/protocol/infrastructure/vaas/) page. ??? child "Struct `VM`" @@ -232,7 +232,7 @@ The way a message is received and handled depends on the environment. ??? interface "Example" ```solidity - --8<-- 'code/build/core-messaging/core-contracts/receiveMessageEVM.sol' + --8<-- 'code/products/messaging/guides/core-contracts/receiveMessageEVM.sol' ``` View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/evm/src/01_hello_world){target=\_blank} repository on GitHub. @@ -251,7 +251,7 @@ The way a message is received and handled depends on the environment. ??? interface "Example" ```rust - --8<-- 'code/build/core-messaging/core-contracts/receiveMessageSolana.rs' + --8<-- 'code/products/messaging/guides/core-contracts/receiveMessageSolana.rs' ``` View the complete Hello World example in the [Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding/tree/main/solana/programs/01_hello_world){target=\_blank} repository on GitHub. @@ -269,15 +269,15 @@ require(isRegisteredSender(emitterChainId, emitterAddress), "Invalid emitter"); This check can be applied after the VAA is parsed, ensuring only authorized senders can interact with the receiving contract. Trusted emitters can be registered using a method like `setRegisteredSender` during contract deployment or initialization. ```typescript ---8<-- 'code/build/core-messaging/core-contracts/receiveEmitterCheck.ts' +--8<-- 'code/products/messaging/guides/core-contracts/receiveEmitterCheck.ts' ``` #### Additional Checks -In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/learn/infrastructure/vaas/){target=\_blank}, including: +In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/docs/protocol/infrastructure/vaas/){target=\_blank}, including: - **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled? -- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? +- **Consistency level** - for the chain this message came from, is the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} level enough to guarantee the transaction won't be reverted after taking some action? The VAA digest is separate from the VAA body but is also relevant. It can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety. diff --git a/build/core-messaging/wormhole-relayers.md b/products/messaging/guides/wormhole-relayers.md similarity index 87% rename from build/core-messaging/wormhole-relayers.md rename to products/messaging/guides/wormhole-relayers.md index f8d17a11d..a326383b9 100644 --- a/build/core-messaging/wormhole-relayers.md +++ b/products/messaging/guides/wormhole-relayers.md @@ -8,18 +8,18 @@ categories: Relayers, Basics ## Introduction -The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/infrastructure/relayers/run-relayer/) is available for more complex needs. +The Wormhole-deployed relayers provide a mechanism for contracts on one blockchain to send messages to contracts on another without requiring off-chain infrastructure. Through the Wormhole relayer module, developers can use an untrusted delivery provider to transport VAAs, saving the need to build and maintain custom relaying solutions. The option to [run a custom relayer](/docs/protocol/infrastructure-guides/run-relayer/) is available for more complex needs. This section covers the components and interfaces involved in using the Wormhole relayer module, such as message sending and receiving, delivery guarantees, and considerations for building reliable and efficient cross-chain applications. Additionally, you'll find details on how to handle specific implementation scenarios and track message delivery progress using the Wormhole CLI tool. ## Get Started with the Wormhole Relayer -Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/build/start-building/supported-networks/) page. +Before getting started, it's important to note that the Wormhole-deployed relayer configuration is currently **limited to EVM environments**. The complete list of EVM environment blockchains is on the [Supported Networks](/docs/products/reference/supported-networks/) page. To interact with the Wormhole relayer, you'll need to create contracts on the source and target chains to handle the sending and receiving of messages. No off-chain logic needs to be implemented to take advantage of Wormhole-powered relaying.
- ![Wormhole Relayer](/docs/images/build/core-messaging/wormhole-relayers/relayer-1.webp) + ![Wormhole Relayer](/docs/images/products/messaging/guides/wormhole-relayers/relayer-1.webp)
The components outlined in blue must be implemented.
@@ -37,12 +37,12 @@ To start interacting with the Wormhole relayer in your contracts, you'll need to To easily integrate with the Wormhole relayer interface, you can use the [Wormhole Solidity SDK](https://github.com/wormhole-foundation/wormhole-solidity-sdk){target=\_blank}. -To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/build/reference/contract-addresses/#wormhole-relayer) reference page. +To retrieve the contract address of the Wormhole relayer, refer to the Wormhole relayer section on the [Contract Addresses](/docs/products/reference/contract-addresses/#wormhole-relayer) reference page. Your initial set up should resemble the following: ```solidity ---8<-- 'code/build/core-messaging/wormhole-relayers/ExampleContract.sol' +--8<-- 'code/products/messaging/guides/wormhole-relayers/ExampleContract.sol' ``` The code provided sets up the basic structure for your contract to interact with the Wormhole relayer using the address supplied to the constructor. By leveraging methods from the `IWormholeRelayer` interface, you can implement message sending and receiving functionalities. The following sections will detail the specific methods you need to use for these tasks. @@ -52,7 +52,7 @@ The code provided sets up the basic structure for your contract to interact with To send a message to a contract on another EVM chain, you can call the `sendPayloadToEvm` method provided by the `IWormholeRelayer` interface. ```solidity ---8<-- 'code/build/core-messaging/wormhole-relayers/sendPayloadToEvm.sol' +--8<-- 'code/products/messaging/guides/wormhole-relayers/sendPayloadToEvm.sol' ``` !!! tip @@ -61,7 +61,7 @@ To send a message to a contract on another EVM chain, you can call the `sendPayl The `sendPayloadToEvm` method is marked `payable` to receive fee payment for the transaction. The value to attach to the invocation is determined by calling the `quoteEVMDeliveryPrice`, which provides an estimate of the cost of gas on the target chain. ```solidity ---8<-- 'code/build/core-messaging/wormhole-relayers/quoteEVMDeliveryPrice.sol' +--8<-- 'code/products/messaging/guides/wormhole-relayers/quoteEVMDeliveryPrice.sol' ``` This method should be called before sending a message, and the value returned for `nativePriceQuote` should be attached to the call to send the payload to cover the transaction's cost on the target chain. @@ -69,7 +69,7 @@ This method should be called before sending a message, and the value returned fo In total, sending a message across EVM chains can be as simple as getting a fee quote and sending the message as follows: ```solidity ---8<-- 'code/build/core-messaging/wormhole-relayers/getQuoteAndSend.sol' +--8<-- 'code/products/messaging/guides/wormhole-relayers/getQuoteAndSend.sol' ``` ### Receive a Message @@ -77,7 +77,7 @@ In total, sending a message across EVM chains can be as simple as getting a fee To receive a message using a Wormhole relayer, the target contract must implement the [`IWormholeReceiver`](https://github.com/wormhole-foundation/wormhole-relayer-solidity-sdk/blob/main/src/interfaces/IWormholeReceiver.sol){target=\_blank} interface, as shown in the [previous section](#interact-with-the-wormhole-relayer). ```solidity ---8<-- 'code/build/core-messaging/wormhole-relayers/receiveWormholeMessages.sol' +--8<-- 'code/products/messaging/guides/wormhole-relayers/receiveWormholeMessages.sol' ``` The logic inside the function body may be whatever business logic is required to take action on the specific payload. @@ -124,7 +124,7 @@ Some implementation details should be considered during development to ensure sa ## Track the Progress of Messages with the Wormhole CLI -While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/build/toolkit/cli/) tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: +While no off-chain programs are required, a developer may want to track the progress of messages in flight. To track the progress of messages in flight, use the [Wormhole CLI](/docs/tools/cli/get-started/){target=\_blank} tool's `status` subcommand. As an example, you can use the following commands to track the status of a transfer by providing the environment, origin network, and transaction hash to the `worm status` command: === "Mainnet" @@ -138,8 +138,8 @@ While no off-chain programs are required, a developer may want to track the prog worm status testnet ethereum INSERT_TRANSACTION_HASH ``` -See the [Wormhole CLI tool docs](/docs/build/toolkit/cli/) for installation and usage. +See the [Wormhole CLI tool docs](/docs/tools/cli/get-started/){target=\_blank} for installation and usage. ## Step-by-Step Tutorial -For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/tutorials/solidity-sdk/cross-chain-contracts/) tutorial. +For detailed, step-by-step guidance on creating cross-chain contracts that interact with the Wormhole relayer, refer to the [Create Cross-Chain Contracts](/docs/products/messaging/tutorials/cross-chain-contracts/) tutorial. diff --git a/products/messaging/overview.md b/products/messaging/overview.md new file mode 100644 index 000000000..1de0a608d --- /dev/null +++ b/products/messaging/overview.md @@ -0,0 +1,64 @@ +--- +title: Messaging Overview +description: With Wormhole Messaging, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Basics +--- + +# Messaging Overview + +Wormhole Messaging is the core protocol of the Wormhole ecosystem—a generic, multichain message-passing layer that enables secure, fast communication between blockchains. It solves the critical problem of blockchain isolation by allowing data and assets to move freely across networks, empowering developers to build true multichain applications. + +## Key Features + +- **Multichain messaging**: Send arbitrary data between blockchains, enabling xDapps, governance actions, or coordination across ecosystems. +- **Decentralized validation**: A network of independent [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observes and signs multichain messages, producing [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} that ensure integrity. +- **Composable architecture**: Works with smart contracts, token bridges, or decentralized applications, providing a flexible foundation for multichain use cases. + +## How It Works + +The messaging flow consists of several core components: + +1. **Source chain (emitter contract)**: A contract emits a message by calling the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain. +2. **Guardian Network**: [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} observe the message, validate it, and generate a signed [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +3. **Relayers**: Off-chain or on-chain [relayers](/docs/protocol/infrastructure/relayer/){target=\_blank} transport the VAA to the destination chain. +4. **Target chain (recipient contract)**: The [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the destination chain verifies the VAA and triggers the specified application logic. + +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) + +## Use Cases + +Wormhole Messaging enables a wide range of multichain applications. Below are common use cases and the Wormhole stack components you can use to build them. + +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate actions across chains. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch rates and prices in real-time. + +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Relay verified data. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Aggregate multi-chain sources. + +- **Gas Abstraction** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Coordinate gas logic. + - [**Native Token Transfers**](/docs/products/native-token-transfers/overview/){target=\_blank}: Handle native token swaps. + +- **Bridging Intent Library** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Dispatch and execute intents. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Execute user-defined bridging intents. + +- **Decentralized Social Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** + + - [**Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Facilitate decentralized interactions. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Enable tokenized rewards. + +## Next Steps + +Follow these steps to work with Wormhole Messaging: + +- [**Get Started with Messaging**](/docs/products/messaging/get-started/){target=\_blank}: Use the core protocol to publish a multichain message and return transaction info with VAA identifiers. +- [**Use Wormhole Relayers**](/docs/products/messaging/guides/wormhole-relayers/){target=\_blank}: Send and receive messages without off-chain infrastructure. + diff --git a/products/messaging/tutorials/.pages b/products/messaging/tutorials/.pages new file mode 100644 index 000000000..e4e12fdcb --- /dev/null +++ b/products/messaging/tutorials/.pages @@ -0,0 +1,5 @@ +title: Tutorials +nav: +- 'Create Messaging Contracts': cross-chain-contracts.md +- 'Create Token Transfer Contracts': cross-chain-token-contracts.md +- 'Replace Outdated Signatures in VAAs': replace-signatures.md \ No newline at end of file diff --git a/tutorials/solidity-sdk/cross-chain-contracts.md b/products/messaging/tutorials/cross-chain-contracts.md similarity index 83% rename from tutorials/solidity-sdk/cross-chain-contracts.md rename to products/messaging/tutorials/cross-chain-contracts.md index 8f7d51a0b..72b8c90f7 100644 --- a/tutorials/solidity-sdk/cross-chain-contracts.md +++ b/products/messaging/tutorials/cross-chain-contracts.md @@ -15,15 +15,15 @@ Wormhole's messaging infrastructure simplifies data transmission, event triggeri By the end of this tutorial, you will have not only built a fully functioning cross-chain message sender and receiver using Solidity but also developed a comprehensive understanding of how to interact with the Wormhole relayer, manage cross-chain costs, and ensure your smart contracts are configured correctly on both source and target chains. -This tutorial assumes a basic understanding of Solidity and smart contract development. Before diving in, it may be helpful to review [the basics of Wormhole](/docs/learn/){target=\_blank} to familiarize yourself with the protocol. +This tutorial assumes a basic understanding of Solidity and smart contract development. Before diving in, it may be helpful to review [the basics of Wormhole](/docs/protocol/introduction/){target=\_blank} to familiarize yourself with the protocol. ## Wormhole Overview -We'll interact with two key Wormhole components: the [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} and the [Wormhole Core Contracts](/docs/learn/infrastructure/core-contracts/){target=\_blank}. The relayer handles cross-chain message delivery and ensures the message is accurately received on the target chain. This allows smart contracts to communicate across blockchains without developers worrying about the underlying complexity. +We'll interact with two key Wormhole components: the [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} and the [Wormhole Core Contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank}. The relayer handles cross-chain message delivery and ensures the message is accurately received on the target chain. This allows smart contracts to communicate across blockchains without developers worrying about the underlying complexity. Additionally, we'll rely on the Wormhole relayer to automatically determine cross-chain transaction costs and facilitate payments. This feature simplifies cross-chain development by allowing you to specify only the target chain and the message. The relayer handles the rest, ensuring that the message is transmitted with the appropriate fee. -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) ## Prerequisites @@ -57,7 +57,7 @@ Key functions include: Here's the core of the contract: ```solidity ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-1.sol:24:43" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-1.sol:24:43" ``` You can find the full code for the `MessageSender.sol` below. @@ -65,7 +65,7 @@ You can find the full code for the `MessageSender.sol` below. ??? code "MessageSender.sol" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-1.sol" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-1.sol" ``` ### Receiver Contract: MessageReceiver @@ -83,8 +83,8 @@ Key implementation details include: - **`isRegisteredSender`** - restricts the processing of messages to only those from registered senders, preventing unauthorized cross-chain communication ```solidity ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol:12:13" ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol:22:39" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol:12:13" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol:22:39" ``` #### Message Processing @@ -92,7 +92,7 @@ Key implementation details include: The `receiveWormholeMessages` is the core function that processes the received message. It checks that the Wormhole relayer sent the message, decodes the payload, and emits an event with the message content. It is essential to verify the message sender to prevent unauthorized messages. ```solidity ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol:42:64" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol:42:64" ``` You can find the full code for the `MessageReceiver.sol` below. @@ -100,7 +100,7 @@ You can find the full code for the `MessageReceiver.sol` below. ??? code "MessageReceiver.sol" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-2.sol" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-2.sol" ``` ## Deploy Contracts @@ -174,7 +174,7 @@ The repository includes: The expected output should be similar to this: ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-7.html" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-7.html" ### Deployment Process @@ -185,36 +185,36 @@ Both deployment scripts, `deploySender.ts` and `deployReceiver.ts`, perform the === "`chains.json`" ```json - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-9.json" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-9.json" ``` === "`deploySender.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts:14:25" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts:14:25" ``` === "`deployReceiver.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts:14:25" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts:14:25" ``` !!! note - The `chains.json` file contains the configuration details for the Avalanche Fuji and Celo Alfajores Testnets. You can modify this file to add more networks if needed. For a complete list of contract addresses, visit the [reference page](/docs/build/reference/){target=\_blank}. + The `chains.json` file contains the configuration details for the Avalanche Fuji and Celo Alfajores Testnets. You can modify this file to add more networks if needed. For a complete list of contract addresses, visit the [reference page](/docs/products/reference/contract-addresses/){target=\_blank}. 2. **Set up provider and wallet** - the scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction === "`deploySender.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts:33:34" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts:33:34" ``` === "`deployReceiver.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts:31:32" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts:31:32" ``` 3. **Deploy the contract** - the contract is deployed to the network specified in the configuration. Upon successful deployment, the contract address is returned, which is crucial for interacting with the contract later on @@ -222,13 +222,13 @@ Both deployment scripts, `deploySender.ts` and `deployReceiver.ts`, perform the === "`deploySender.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts:50:53" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts:50:53" ``` === "`deployReceiver.ts`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts:51:54" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts:51:54" ``` 4. **Register the `MessageSender` on the target chain** - after you deploy the `MessageReceiver` contract on the Celo Alfajores network, the sender contract address from Avalanche Fuji needs to be registered. This ensures that only messages from the registered `MessageSender` contract are processed @@ -236,7 +236,7 @@ Both deployment scripts, `deploySender.ts` and `deployReceiver.ts`, perform the This additional step is essential to enforce emitter validation, preventing unauthorized senders from delivering messages to the `MessageReceiver` contract ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts:67:81" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts:67:81" ``` You can find the full code for the `deploySender.ts` and `deployReceiver.ts` below. @@ -244,13 +244,13 @@ You can find the full code for the `deploySender.ts` and `deployReceiver.ts` bel ??? code "deploySender.ts" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-5.ts" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-5.ts" ``` ??? code "deployReceiver.ts" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-6.ts" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-6.ts" ``` ### Deploy the Sender Contract @@ -265,7 +265,7 @@ The sender contract will handle quoting and sending messages cross-chain. 2. Once deployed, the contract address will be displayed. You may check the contract on the [Avalanche Fuji Explorer](https://testnet.snowtrace.io/){target=\_blank} ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-8.html" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-8.html" ### Deploy the Receiver Contract @@ -295,7 +295,7 @@ Let's break down the script step by step. 2. **`deployedContracts.json`** - stores the addresses of the deployed sender and receiver contracts. This file is dynamically updated when contracts are deployed, but users can also manually add their own deployed contract addresses if needed ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:11:23" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:11:23" ``` 2. **Configure the provider and signer** - the script first reads the chain configurations and extracts the contract addresses. One essential step in interacting with a blockchain is setting up a _provider_. A provider is your connection to the blockchain network. It allows your script to interact with the blockchain, retrieve data, and send transactions. In this case, we're using a JSON-RPC provider @@ -303,31 +303,31 @@ Let's break down the script step by step. Next, we configure the wallet, which will be used to sign transactions. The wallet is created using the private key and the provider. This ensures that all transactions sent from this wallet are broadcast to the Avalanche Fuji network: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:47:48" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:47:48" ``` After setting up the wallet, the script loads the ABI for the `MessageSender.sol` contract and creates an instance of it: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:51:56" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:51:56" ``` 3. **Set up the message details** - the next part of the script defines the target chain (Celo) and the target address (the receiver contract on Celo): ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:68:69" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:68:69" ``` You can customize the message that will be sent across chains: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:72:72" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:72:72" ``` 4. **Estimate cross-chain cost** - before sending the message, we dynamically calculate the cross-chain cost using the `quoteCrossChainCost` function: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:75:75" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:75:75" ``` This ensures that the transaction includes enough funds to cover the gas fees for the cross-chain message. @@ -335,13 +335,13 @@ Let's break down the script step by step. 5. **Send a message** - with everything set up, the message is sent using the `sendMessage` function: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:78:85" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:78:85" ``` After sending, the script waits for the transaction to be confirmed: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts:88:88" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts:88:88" ``` 6. **Run the script** - to send the message, run the following command: @@ -354,14 +354,14 @@ If everything is set up correctly, the message will be sent from the Avalanche F The console should output something similar to this: ---8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-4.html" +--8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-4.html" You can find the full code for the `sendMessage.ts` below. ??? code "sendMessage.ts" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-contracts/snippet-3.ts" + --8<-- "code/products/messaging/tutorials/cross-chain-contracts/snippet-3.ts" ``` ## Conclusion diff --git a/tutorials/solidity-sdk/cross-chain-token-contracts.md b/products/messaging/tutorials/cross-chain-token-contracts.md similarity index 86% rename from tutorials/solidity-sdk/cross-chain-token-contracts.md rename to products/messaging/tutorials/cross-chain-token-contracts.md index d628381bb..2eb4a9bba 100644 --- a/tutorials/solidity-sdk/cross-chain-token-contracts.md +++ b/products/messaging/tutorials/cross-chain-token-contracts.md @@ -54,7 +54,7 @@ To simplify this process, we've included a tool for verifying if a token has an 5. The expected output when the token has an attestation: - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-10.html" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-10.html" Using this tool ensures that you only attempt to transfer tokens with verified attestations, avoiding any potential issues during the cross-chain transfer process. @@ -111,8 +111,8 @@ Let's start writing the `CrossChainSender` contract: 2. Open the file. First, we'll start with the imports and the contract setup: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol:1:14" - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol:58:58" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol:1:14" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol:58:58" ``` This sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. @@ -122,7 +122,7 @@ Let's start writing the `CrossChainSender` contract: 3. Next, let's add a function that estimates the cost of sending tokens across chains: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol:17:28" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol:17:28" ``` This function, `quoteCrossChainDeposit`, helps calculate the cost of transferring tokens to a different chain. It factors in the delivery cost and the cost of publishing a message via the Wormhole protocol. @@ -130,7 +130,7 @@ Let's start writing the `CrossChainSender` contract: 4. Finally, we'll add the function that sends the tokens across chains: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol:31:57" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol:31:57" ``` This `sendCrossChainDeposit` function is where the actual token transfer happens. It sends the tokens to the recipient on the target chain using the Wormhole protocol. @@ -157,7 +157,7 @@ You can find the complete code for the `CrossChainSender.sol` below. ??? code "MessageSender.sol" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-1.sol" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-1.sol" ``` ### Receiver Contract: CrossChainReceiver @@ -175,8 +175,8 @@ Let's start writing the `CrossChainReceiver` contract: 2. Open the file. First, we'll start with the imports and the contract setup: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol:1:14" - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol:40:40" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol:1:14" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol:40:40" ``` Similar to the `CrossChainSender` contract, this sets up the basic structure of the contract, including the necessary imports and the constructor that initializes the contract with the Wormhole-related addresses. @@ -184,7 +184,7 @@ Let's start writing the `CrossChainReceiver` contract: 3. Next, let's add a function inside the contract to handle receiving the payload and tokens: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol:17:39" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol:17:39" ``` This `receivePayloadAndTokens` function processes the tokens and payload sent from another chain, decodes the recipient address, and transfers the tokens to them using the Wormhole protocol. This function also validates the emitter (`sourceAddress`) to ensure the message comes from a trusted sender. @@ -195,14 +195,14 @@ Let's start writing the `CrossChainReceiver` contract: - The `sourceAddress` is checked against a list of registered senders using the `isRegisteredSender` modifier, which verifies if the emitter is allowed to send tokens to this contract - The recipient address is decoded from the payload, and the received tokens are transferred to them using the ERC-20 interface -After we call `sendTokenWithPayloadToEvm` on the source chain, the message goes through the standard Wormhole message lifecycle. Once a [VAA (Verifiable Action Approval)](/docs/learn/infrastructure/vaas/){target=\_blank} is available, the delivery provider will call `receivePayloadAndTokens` on the target chain and target address specified, with the appropriate inputs. +After we call `sendTokenWithPayloadToEvm` on the source chain, the message goes through the standard Wormhole message lifecycle. Once a [VAA (Verifiable Action Approval)](/docs/protocol/infrastructure/vaas/){target=\_blank} is available, the delivery provider will call `receivePayloadAndTokens` on the target chain and target address specified, with the appropriate inputs. ??? tip "Understanding the `TokenReceived` Struct" Let’s delve into the fields provided to us in the `TokenReceived` struct: ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-11.sol" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-11.sol" ``` - **`tokenHomeAddress`** - the original address of the token on its native chain. This is the same as the token field in the call to `sendTokenWithPayloadToEvm` unless the original token sent is a Wormhole-wrapped token. In that case, this will be the address of the original version of the token (on its native chain) in Wormhole address format (left-padded with 12 zeros) @@ -220,7 +220,7 @@ You can find the complete code for the `CrossChainReceiver.sol` contract below: ??? code "CrossChainReceiver.sol" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-2.sol" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-2.sol" ``` ## Deploy the Contracts @@ -244,12 +244,12 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 3. Open the `config.json` file and add the following configuration: ```json - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-3.json" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-3.json" ``` This file specifies the details for each chain where you plan to deploy your contracts, including the RPC URL, the `TokenBridge` address, the Wormhole relayer, and the Wormhole Core Contract. - For a complete list of Wormhole contract addresses on various blockchains, refer to the [Wormhole Contract Addresses](/docs/build/reference/contract-addresses/){target=_blank}. + For a complete list of Wormhole contract addresses on various blockchains, refer to the [Wormhole Contract Addresses](/docs/products/reference/contract-addresses/){target=_blank}. !!! note You can add your desired chains to this file by specifying the required fields for each chain. In this example, we use the Avalanche Fuji and Celo Alfajores Testnets. @@ -296,7 +296,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract The expected output should be similar to this: - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-6.html" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-6.html" 4. **Write the deployment script** - you’ll need a script to automate the deployment of your contracts. Let’s create the deployment script @@ -309,7 +309,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 2. Open the file and load imports and configuration: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:1:7" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:1:7" ``` Import the required libraries and modules to interact with Ethereum, handle file paths, load environment variables, and enable user interaction via the terminal. @@ -317,7 +317,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 3. Define interfaces to use for chain configuration and contract deployment: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:9:25" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:9:25" ``` These interfaces define the structure of the chain configuration and the contract deployment details. @@ -325,7 +325,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 4. Load and select the chains for deployment: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:27:47" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:27:47" ``` The `loadConfig` function reads the chain configuration from the `config.json` file, and the `selectChain` function allows the user to choose the source and target chains for deployment interactively. The user is prompted in the terminal to select which chains to use, making the process interactive and user-friendly. @@ -333,7 +333,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 5. Define the main function for deployment and load the chain configuration: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:48:53" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:48:53" ``` - The `main` function is the entry point for the deployment script @@ -342,7 +342,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 6. Set up provider and wallet: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:54:57" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:54:57" ``` The scripts establish a connection to the blockchain using a provider and create a wallet instance using a private key. This wallet is responsible for signing the deployment transaction on the source chain. @@ -350,7 +350,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 7. Read the compiled contracts: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:58:66" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:58:66" ``` - This code reads the `CrossChainSender.json` file, the compiled output of the `CrossChainSender.sol` contract @@ -360,7 +360,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 8. Extract the contract ABI and bytecode: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:68:69" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:68:69" ``` - **ABI (Application Binary Interface)** - defines the structure of the contract’s functions, events, and data types, allowing the front end to interact with the contract on the blockchain @@ -369,7 +369,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 9. Create the Contract Factory: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:71:75" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:71:75" ``` - **`ethers.ContractFactory`** - creates a new contract factory using the ABI, bytecode, and a wallet (representing the signer). The contract factory is responsible for deploying instances of the contract to the blockchain @@ -379,12 +379,12 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract === "`CrossChainSender`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:77:83" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:77:83" ``` === "`CrossChainReceiver`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:91:115" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:91:115" ``` Both functions deploy the respective contracts to the selected chains. @@ -400,12 +400,12 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract === "`senderAddress`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:86:89" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:86:89" ``` === "`receiverAddress`" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:118:121" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:118:121" ``` You may display the deployed contract addresses in the terminal or save them to a JSON file for future reference. @@ -413,7 +413,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 12. Register the `CrossChainSender` address on the target chain: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:128:139" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:128:139" ``` After you deploy the `CrossChainReceiver` contract on the target network, the sender contract address from the source chain needs to be registered. This ensures that only messages from the registered `CrossChainSender` contract are processed. @@ -424,7 +424,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract ???- example "Save Deployment Details Example" ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:145:185" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:145:185" ``` Add your desired logic to save the deployed contract addresses in a JSON file (or another format). This will be important later when transferring tokens, as you'll need these addresses to interact with the deployed contracts. @@ -432,7 +432,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract 14. Handle errors and finalize the script: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts:186:201" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts:186:201" ``` The try-catch block wraps the deployment logic to catch any errors that may occur. @@ -447,7 +447,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract ??? code "deploy.ts" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-4.ts" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-4.ts" ``` 5. **Add your private key** - you'll need to provide your private key. It allows your deployment script to sign the transactions that deploy the smart contracts to the blockchain. Without it, the script won't be able to interact with the blockchain on your behalf @@ -481,7 +481,7 @@ Now that you've written the `CrossChainSender` and `CrossChainReceiver` contract If you followed the logic provided in the full code above, your terminal output should look something like this: ---8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-7.html" +--8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-7.html" ## Transfer Tokens Across Chains @@ -505,7 +505,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` 2. Open the file. Start with the necessary imports, interfaces and configurations: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:1:25" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:1:25" ``` These imports include the essential libraries for interacting with Ethereum, handling file paths, loading environment variables, and managing user input. @@ -514,7 +514,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:27:47" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:27:47" ``` These functions load the network and contract details that were saved during deployment. @@ -524,7 +524,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` Refer to the deployed contracts and create logic as desired. In our example, we made this process interactive, allowing users to select the source and target chains from all the historically deployed contracts. This interactive approach helps ensure the correct chains are selected for the token transfer. ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:49:101" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:49:101" ``` 2. **Implement the token transfer logic** @@ -532,7 +532,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` 1. Start the `main` function: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:103:139" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:103:139" ``` The `main` function is where the token transfer logic will reside. It loads the chain and contract details, sets up the wallet and provider, and loads the `CrossChainSender` contract. @@ -542,7 +542,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` You'll now ask the user for the token contract address, the recipient address on the target chain, and the amount of tokens to transfer. ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:147:171" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:147:171" ``` This section of the script prompts the user for the token contract address and the recipient's address, fetches the token's decimal value, and parses the amount accordingly. @@ -552,7 +552,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` Finally, initiate the cross-chain transfer and log the details. ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:174:204" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:174:204" ``` This part of the script first approves the token transfer, then initiates the cross-chain transfer using the `CrossChainSender` contract, and finally logs the transaction hash for the user to track. @@ -560,7 +560,7 @@ In this step, you'll write a script to transfer tokens across chains using the ` 4. Finalize the script: ```typescript - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts:205:208" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts:205:208" ``` This section finalizes the script by calling the `main` function and handling any errors that may occur during the token transfer process. @@ -570,7 +570,7 @@ You can find the full code for the `transfer.ts` file below: ??? code "transfer.ts" ```solidity - --8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-5.ts" + --8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-5.ts" ``` ### Transfer Tokens @@ -595,7 +595,7 @@ You can verify the transaction on the [Wormhole Explorer](https://wormholescan.i If you followed the logic provided in the `transfer.ts` file above, your terminal output should look something like this: ---8<-- "code/tutorials/solidity-sdk/cross-chain-token-transfers/snippet-8.html" +--8<-- "code/products/messaging/tutorials/cross-chain-token-transfers/snippet-8.html" !!! note In this example, we demonstrated a token transfer from the Avalanche Fuji Testnet to the Celo Alfajores Testnet. We sent two units of USDC Testnet tokens using the token contract address `0x5425890298aed601595a70ab815c96711a31bc65`. You can replace these details with those relevant to your project or use the same for testing purposes. diff --git a/tutorials/wormholescan/replace-signatures.md b/products/messaging/tutorials/replace-signatures.md similarity index 80% rename from tutorials/wormholescan/replace-signatures.md rename to products/messaging/tutorials/replace-signatures.md index 1ae76cfe2..cb256eb58 100644 --- a/tutorials/wormholescan/replace-signatures.md +++ b/products/messaging/tutorials/replace-signatures.md @@ -9,7 +9,7 @@ description: Learn how to fetch, validate, and replace outdated signatures in Wo ## Introduction -Cross-chain transactions in Wormhole rely on [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank}, which contain signatures from a trusted set of validators called [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank}. These signatures prove that the network approved an action, such as a token transfer. +Cross-chain transactions in Wormhole rely on [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank}, which contain signatures from a trusted set of validators called [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}. These signatures prove that the network approved an action, such as a token transfer. However, the set of Guardians changes over time. If a user generates a transaction and waits too long before redeeming it, the Guardian set may have already changed. This means the VAA will contain outdated signatures from Guardians, who are no longer part of the network, causing the transaction to fail. @@ -57,7 +57,7 @@ In this section, you will create the directory, initialize a Node.js project, in Then, add the following configuration: ```json title="tsconfig.json" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-1.json" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-1.json" ``` 4. **Install dependencies** - add the required packages @@ -87,19 +87,19 @@ In this section, you will create the directory, initialize a Node.js project, in 6. **Set variables** - define key constants in `src/config/constants.ts` ```bash title="src/config/constants.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-2.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-2.ts" ``` - **`RPC`** - endpoint for interacting with an Ethereum RPC node - - **`ETH_CORE`** - [Wormhole's Core Contract address on Ethereum](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} responsible for verifying VAAs + - **`ETH_CORE`** - [Wormhole's Core Contract address on Ethereum](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} responsible for verifying VAAs - **`WORMHOLESCAN_API`** - base URL for querying the Wormholescan API to fetch VAA data and Guardian sets - **`LOG_MESSAGE_PUBLISHED_TOPIC`** - the event signature hash for `LogMessagePublished`, a Wormhole contract event that signals when a VAA has been emitted. This is used to identify relevant logs in transaction receipts - **`TXS`** - list of example transaction hashes that will be used for testing -7. **Define data structure for working with VAAs** - specify the ABI for the Wormhole Core Contract's `parseAndVerifyVM` function, which parses and verifies VAAs. Defining the data structure, also referred to as a [layout](/docs/build/toolkit/typescript-sdk/sdk-layout/){target=\_blank}, for this function ensures accurate decoding and validation of VAAs +7. **Define data structure for working with VAAs** - specify the ABI for the Wormhole Core Contract's `parseAndVerifyVM` function, which parses and verifies VAAs. Defining the data structure, also referred to as a [layout](/docs/tools/typescript-sdk/guides/sdk-layout/){target=\_blank}, for this function ensures accurate decoding and validation of VAAs ```typescript title="src/config/layouts.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-3.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-3.ts" ``` ## Create VAA Handling Functions @@ -109,7 +109,7 @@ In this section, we'll create a series of helper functions in the `src/helpers/v To get started, import the necessary dependencies: ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:1:15" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:1:15" ``` ### Fetch a VAA ID from a Transaction @@ -121,7 +121,7 @@ The VAA ID is structured as follows: chain/emitter/sequence ``` - - `chain` - the [Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} (Ethereum is 2) + - `chain` - the [Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} (Ethereum is 2) - `emitter` - the contract address that emitted the VAA - `sequence` - a unique identifier for the event @@ -138,7 +138,7 @@ Follow the below steps to process the transaction logs and construct the VAA ID: 4. **Construct the VAA ID** - format the extracted data in `chain/emitter/sequence` format ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:17:50" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:17:50" ``` ???- code "Try it out: VAA ID retrieval" @@ -153,7 +153,7 @@ Follow the below steps to process the transaction logs and construct the VAA ID: 2. **Add the function call** ```typescript title="test/fetchVaaId.run.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-5.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-5.ts" ``` 3. **Run the script** @@ -164,7 +164,7 @@ Follow the below steps to process the transaction logs and construct the VAA ID: If successful, the output will be: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-6.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-6.html" If no VAA ID is found, the script will log an error message. @@ -175,7 +175,7 @@ Now that you have the VAA ID, we can use it to fetch the full VAA payload from t Open `src/helpers/vaaHelper.ts` and create the `fetchVaa()` function to iterate through VAA IDs and extract the `vaaBytes` payload. ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:52:67" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:52:67" ``` ???- code "Try it out: VAA retrieval" @@ -190,7 +190,7 @@ Open `src/helpers/vaaHelper.ts` and create the `fetchVaa()` function to iterate 2. **Add the function call** ```typescript title="test/fetchVaa.run.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-7.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-7.ts" ``` 3. **Run the script** @@ -201,7 +201,7 @@ Open `src/helpers/vaaHelper.ts` and create the `fetchVaa()` function to iterate If successful, the output will be: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-8.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-8.html" If no VAA is found, the script will log an error message. @@ -220,7 +220,7 @@ Follow these steps to implement the function: 3. **Decode the response** - check whether the VAA is valid. If it contains outdated signatures, further action will be required to replace them ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:69:107" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:69:107" ``` ???- code "Try it out: VAA Validity" @@ -235,7 +235,7 @@ Follow these steps to implement the function: 2. **Add the function call** ```typescript title="test/checkVaaValidity.run.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-9.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-9.ts" ``` 3. **Run the script** @@ -246,11 +246,11 @@ Follow these steps to implement the function: If the VAA is valid, the output will be: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-10.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-10.html" If invalid, the output will include the reason: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-11.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-11.html" ### Fetch Observations (VAA Signatures) @@ -259,7 +259,7 @@ Before replacing outdated signatures, we need to fetch the original VAA signatur Inside `src/helpers/vaaHelper.ts`, create the `fetchObservations()` function to query the Wormholescan API for observations related to a given VAA. Format the response by converting Guardian addresses to lowercase for consistency, and return an empty array if an error occurs. ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:109:125" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:109:125" ``` ???- code "Try it out: Fetch Observations" @@ -274,7 +274,7 @@ Inside `src/helpers/vaaHelper.ts`, create the `fetchObservations()` function to 2. **Add the function call** ```typescript title="test/fetchObservations.run.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-12.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-12.ts" ``` 3. **Run the script** @@ -285,7 +285,7 @@ Inside `src/helpers/vaaHelper.ts`, create the `fetchObservations()` function to If successful, the output will be: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-13.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-13.html" If no observations are found, the script will log an error message. @@ -296,7 +296,7 @@ Now that we have the original VAA signatures, we must fetch the latest Guardian Create the `fetchGuardianSet()` function inside `src/helpers/vaaHelper.ts` to fetch the latest Guardian set. ```typescript title="src/helpers/vaaHelper.ts" ---8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:126:142" +--8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:126:142" ``` ???- code "Try it out: Fetch Guardian Set" @@ -311,7 +311,7 @@ Create the `fetchGuardianSet()` function inside `src/helpers/vaaHelper.ts` to fe 2. **Add the function call** ```typescript title="test/fetchGuardianSet.run.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-14.ts" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-14.ts" ``` 3. **Run the script** @@ -322,7 +322,7 @@ Create the `fetchGuardianSet()` function inside `src/helpers/vaaHelper.ts` to fe If successful, the output will be: - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-15.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-15.html" If an error occurs while fetching the Guardian set, a `500` status error will be logged. @@ -333,9 +333,9 @@ With the full VAA, Guardian signatures, and the latest Guardian set, we can now 1. **Create the `replaceSignatures()` function** - open `src/helpers/vaaHelper.ts` and add the function header. To catch and handle errors properly, all logic will be wrapped inside a `try` block ```typescript title="src/helpers/vaaHelper.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:144:152" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:144:152" // Add logic in the following steps here - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:280:283" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:280:283" ``` - **`vaa`** - original VAA bytes @@ -346,54 +346,54 @@ With the full VAA, Guardian signatures, and the latest Guardian set, we can now 2. **Validate input data** - ensure all required parameters are present before proceeding. If any required input is missing, the function throws an error to prevent execution with incomplete data. The Guardian set should never be empty; if it is, this likely indicates an error in fetching the Guardian set in a previous step ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:153:156" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:153:156" ``` 3. **Filter valid signatures** - remove signatures from inactive Guardians, keeping only valid ones. If there aren't enough valid signatures to replace the outdated ones, execution is halted to prevent an incomplete or invalid VAA ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:158:163" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:158:163" ``` 4. **Convert valid signatures** - ensure signatures are correctly formatted for verification. Convert hex-encoded signatures if necessary and extract their components ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:165:195" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:165:195" ``` 5. **Deserialize the VAA** - convert the raw VAA data into a structured format for further processing ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:197:202" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:197:202" ``` 6. **Identify outdated signatures** - compare the current VAA signatures with the newly formatted ones to detect which signatures belong to outdated Guardians. Remove these outdated signatures to ensure only valid ones remain ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:204:217" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:204:217" ``` 7. **Replace outdated signatures** - substitute outdated signatures with valid ones while maintaining the correct number of signatures. If there aren’t enough valid replacements, execution stops ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:219:237" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:219:237" ``` 8. **Serialize the updated VAA** - reconstruct the VAA with the updated signatures and convert it into a format suitable for submission ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:239:250" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:239:250" ``` 9. **Send the updated VAA for verification and handle errors** - submit the updated VAA to an Ethereum RPC node for validation, ensuring it can be proposed for Guardian approval. If an error occurs during submission or signature replacement, log the issue and prevent further execution ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:252:279" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:252:279" ``` ???- code "Complete Function" ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-4.ts:144:283" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-4.ts:144:283" ``` ## Create Script to Replace Outdated VAA Signatures @@ -403,19 +403,19 @@ Now that we have all the necessary helper functions, we will create a script to 1. **Open the file** - inside `src/scripts/replaceSignatures.ts`, import the required helper functions needed to process the VAAs ```typescript title="src/scripts/replaceSignatures.ts" - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-16.ts:1:9" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-16.ts:1:9" ``` 2. **Define the main execution function** - add the following function inside `src/scripts/replaceSignatures.ts` to process each transaction in `TXS`, going step by step through the signature replacement process ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-16.ts:11:51" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-16.ts:11:51" ``` 3. **Make the script executable** - ensure it runs when executed ```typescript - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-16.ts:53:53" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-16.ts:53:53" ``` To run the script, use the following command: @@ -424,7 +424,7 @@ Now that we have all the necessary helper functions, we will create a script to npx tsx src/scripts/replaceSignatures.ts ``` - --8<-- "code/tutorials/wormholescan/replace-signatures/replace-sigs-17.html" + --8<-- "code/products/messaging/tutorials/replace-signatures/replace-sigs-17.html" The script logs each step, skipping valid VAAs, replacing outdated signatures for invalid VAAs, and logging any errors. It then completes with a valid VAA ready for submission. diff --git a/products/multigov/.pages b/products/multigov/.pages new file mode 100644 index 000000000..515cb66d0 --- /dev/null +++ b/products/multigov/.pages @@ -0,0 +1,8 @@ +title: MultiGov +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- tutorials +- concepts +- 'FAQs': faqs.md diff --git a/products/multigov/concepts/.pages b/products/multigov/concepts/.pages new file mode 100644 index 000000000..9ef6dde62 --- /dev/null +++ b/products/multigov/concepts/.pages @@ -0,0 +1,3 @@ +title: Concepts +nav: +- 'Architecture': architecture.md \ No newline at end of file diff --git a/learn/governance/architecture.md b/products/multigov/concepts/architecture.md similarity index 89% rename from learn/governance/architecture.md rename to products/multigov/concepts/architecture.md index 85dbdde1e..a28d63706 100644 --- a/learn/governance/architecture.md +++ b/products/multigov/concepts/architecture.md @@ -6,7 +6,13 @@ categories: MultiGov # MultiGov Architecture -MultiGov employs a hub-and-spoke model to enable cross-chain governance, utilizing Wormhole's interoperability infrastructure for secure cross-chain communication. This architecture allows coordinated decision-making across multiple blockchain networks while maintaining a central coordination point. +MultiGov uses a hub-and-spoke architecture to coordinate governance across multiple blockchains. The hub chain is the central controller that handles proposal creation, vote aggregation, and execution. Spoke chains allow token holders to vote locally and can also execute proposal outcomes specific to their network. + +Wormhole’s multichain messaging infrastructure connects the hub and spokes, enabling secure and efficient chain communication. This design allows DAOs to operate seamlessly across ecosystems while maintaining a unified governance process. + +The diagram below illustrates this high-level architecture. + +![High-level architecture diagram illustrating the hub-and-spoke structure of the MultiGov system. The diagram shows three key components: Hub Chain and two Spoke Chains, interconnected via Wormhole for cross-chain governance.](/docs/images/products/multigov/concepts/architecture/architecture-1.webp) ## Key Components @@ -126,4 +132,4 @@ MultiGov relies on Wormhole's infrastructure for all cross-chain messaging, ensu This architecture ensures that MultiGov can operate securely and efficiently across multiple chains, allowing for truly decentralized and cross-chain governance while maintaining a unified decision-making process. -![detailed multigov architecture diagram](/docs/images/learn/governance/multigov-detailed.webp) +![detailed multigov architecture diagram](/docs/images/products/multigov/concepts/architecture/architecture-2.webp) diff --git a/build/multigov/faq.md b/products/multigov/faqs.md similarity index 71% rename from build/multigov/faq.md rename to products/multigov/faqs.md index 2dd2f401a..1a8529f8e 100644 --- a/build/multigov/faq.md +++ b/products/multigov/faqs.md @@ -1,14 +1,16 @@ --- -title: MultiGov Technical FAQs +title: MultiGov FAQs description: Find answers to common questions about MultiGov, covering cross-chain governance, technical setup, security, proposal creation, and more. categories: MultiGov --- # FAQs -## Technical Questions +## What is MultiGov? -### How does MultiGov ensure security in cross-chain communication? +MultiGov is a cross-chain governance system that extends traditional DAO governance across multiple blockchain networks. It leverages Wormhole's interoperability infrastructure for seamless voting and proposal mechanisms across various chains. + +## How does MultiGov ensure security in cross-chain communication? MultiGov leverages Wormhole's robust cross-chain communication protocol. It implements several security measures: @@ -17,42 +19,38 @@ MultiGov leverages Wormhole's robust cross-chain communication protocol. It impl - Authorized participant validation to maintain the integrity of the governance process - Replay attack prevention by tracking executed messages -### Can MultiGov integrate with any blockchain? +## Can MultiGov integrate with any blockchain? -MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/build/start-building/supported-networks/). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. +MultiGov can potentially integrate with any blockchain supported by Wormhole. However, specific implementations may vary depending on the chain's compatibility with the Ethereum Virtual Machine (EVM) and its smart contract capabilities. [See the full list of supported networks](/docs/products/reference/supported-networks/#multigov). The current implementation of MultiGov supports an EVM hub and both the EVM and SVM for spokes. -### How are votes aggregated across different chains? +## How are votes aggregated across different chains? Votes are collected on each spoke chain using each chain's `SpokeVoteAggregator`. These votes are then transmitted to the HubVotePool on the hub chain for aggregation and tabulation. The `HubEvmSpokeVoteDecoder` standardizes votes from different EVM chains to ensure consistent processing. -### Can governance upgrade from a single chain to MultiGov? +## Can governance upgrade from a single chain to MultiGov? Yes! MultiGov can support progressively upgrading from a single-chain governance to MultiGov. Moving to MultiGov requires upgrading the token to NTT and adding Flexible Voting to the original Governor. -## Usage Questions - -### How can I create a proposal in MultiGov? +## How can I create a proposal in MultiGov? Proposals are created on the hub chain using the `HubEvmSpokeAggregateProposer` contract or by calling `propose` on the `HubGovernor`. You need to prepare the proposal details, including targets, values, and calldatas. The proposer's voting weight is aggregated across chains using Wormhole queries to determine eligibility. -### How do I vote on a proposal if I hold tokens on a spoke chain? +## How do I vote on a proposal if I hold tokens on a spoke chain? You can vote on proposals via the `SpokeVoteAggregator` contract on the respective spoke chain where you hold your tokens. The votes are then automatically forwarded to the hub chain for aggregation. -### How are approved proposals executed across multiple chains? +## How are approved proposals executed across multiple chains? When a proposal is approved and the timelock period elapses, it's first executed on the hub chain. A proposal can include a cross-chain message by including a call to `dispatch` on the `HubMessageDispatcher`, which sends a message to the relevant spoke chains. On each spoke chain, the `SpokeMessageExecutor` receives, verifies, and automatically executes the instructions using the `SpokeAirlock` as the `msg.sender`. -## Implementation Questions - -### What are the requirements for using MultiGov? +## What are the requirements for using MultiGov? To use MultiGov, your DAO must meet the following requirements: - **ERC20Votes token** - your DAO's token must implement the `ERC20Votes` standard and support `CLOCK_MODE` timestamps for compatibility with cross-chain governance - **Flexible voting support** - your DAO's Governor must support Flexible Voting to function as the Hub Governor. If your existing Governor does not support Flexible Voting, you can upgrade it to enable this feature -### What do I need to set up MultiGov for my project? +## What do I need to set up MultiGov for my project? Get started by filling out the form below: @@ -67,17 +65,17 @@ To set up testing MultiGov for your DAO, you'll need: - Modify and deploy the hub and spoke contracts using the provided scripts - Set up the necessary environment variables and configurations -### Can MultiGov be used with non-EVM chains? +## Can MultiGov be used with non-EVM chains? The current implementation is designed for EVM-compatible chains. However, Solana (non-EVM) voting is currently in development and expected to go live after the EVM contracts. -### How can I customize voting parameters in MultiGov? +## How can I customize voting parameters in MultiGov? Voting parameters such as voting delay, voting period, proposal threshold, and quorum (and others) can be customized in the deployment scripts (`DeployHubContractsSepolia.s.sol` and `DeploySpokeContractsOptimismSepolia.s.sol` as examples for their respective chains). Make sure to adjust these parameters according to your DAO's specific needs before deployment. Remember to thoroughly test your MultiGov implementation on testnets before deploying to Mainnet, and have your contracts audited for additional security. -### How does MultiGov handle potential network issues or temporary chain unavailability? +## How does MultiGov handle potential network issues or temporary chain unavailability? MultiGov includes several mechanisms to handle network issues or temporary chain unavailability: @@ -86,4 +84,17 @@ MultiGov includes several mechanisms to handle network issues or temporary chain 3. **Wormhole retry mechanism** - Wormhole's infrastructure includes retry mechanisms for failed message deliveries, helping ensure cross-chain messages eventually get through 4. **Decentralized relayer network** - Wormhole's decentralized network of relayers helps maintain system availability even if some relayers are offline -However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. \ No newline at end of file +However, prolonged outages on the hub chain or critical spoke chains could potentially disrupt governance activities. Projects should have contingency plans for such scenarios. + +## How does MultiGov differ from traditional DAO governance? + +Unlike traditional DAO governance, which typically operates on a single blockchain, MultiGov allows for coordinated decision-making and proposal execution across multiple chains. This enables more inclusive participation from token holders on different networks and more complex, cross-chain governance actions. + +## What are the main components of MultiGov? + +The main components of MultiGov include: + +- **Hub chain** - central coordination point for governance activities +- **Spoke chains** - additional chains where token holders can participate in governance +- **Wormhole integration** - enables secure cross-chain message passing +- **Governance token** - allows holders to participate in governance across all integrated chains diff --git a/products/multigov/get-started.md b/products/multigov/get-started.md new file mode 100644 index 000000000..e253770d3 --- /dev/null +++ b/products/multigov/get-started.md @@ -0,0 +1,46 @@ +--- +title: Get Started with Multigov +description: Follow this guide to set up your environment and request access to deploy MultiGov contracts for multichain DAO governance using Wormhole messaging. +categories: MultiGov +--- + +# Get Started with Multigov + +## Introduction + +[MultiGov](/docs/products/multigov/overview/){target=\_blank} enables multichain governance using Wormhole messaging. With MultiGov, token holders can create proposals, vote, and execute decisions from any supported chain, eliminating the need to bridge assets or rely on a single governance hub. + +This page walks you through the MultiGov deployment flow—from requesting access with Tally to choosing a network and following the appropriate deployment guide. + +## Prerequisites + +Before deploying MultiGov, you need a governance token deployed on multiple chains (ERC-20 or SPL): + +- **EVM chains**: + - Your token must implement the [`ERC20Votes`](https://docs.openzeppelin.com/contracts/4.x/governance#erc20votes){target=\_blank} standard + - It must support `CLOCK_MODE` timestamps for compatibility with cross-chain voting + +- **Solana**: + - Use an SPL token + - Voting eligibility and weight are managed by the [MultiGov staking program](/docs/products/multigov/concepts/architecture/#spoke-solana-staking-program){target=\_blank} + +## Request Tally Access + +MultiGov integrations are coordinated through [Tally](https://www.tally.xyz/explore){target=\_blank}, a multichain governance platform that powers proposal creation, voting, and execution. + +To get started, fill out the integration [intake form](https://www.tally.xyz/get-started){target=\_blank}. The Tally team will review your application and contact you to discuss deployment and setup requirements. + +Once approved, review the deployment flow below to understand the integration process. Then, follow the appropriate deployment guide to integrate MultiGov with your governance token on EVM chains, Solana, or other supported networks. + +## Deployment Flow + +MultiGov deployments follow a similar structure on both EVM and Solana. This section provides a high-level overview of the end-to-end flow. Each step is explained in more detail in the platform-specific deployment guides linked [below](#next-steps). + +[timeline(wormhole-docs/.snippets/text/products/multigov/deployment-flow-timeline.json)] + +## Next Steps + +You've now completed the initial setup and requested access through Tally. Continue to the deployment guide that matches your governance architecture: + + - [**Deploy on EVM Chains**](/docs/products/multigov/guides/deploy-to-evm){target=\_blank}: Configure and deploy MultiGov smart contracts to EVM-compatible chains. + - [**Deploy on Solana**](/docs/products/multigov/guides/deploy-to-solana){target=\_blank}: Launch the Solana staking program and configure spoke chain participation. \ No newline at end of file diff --git a/products/multigov/guides/.pages b/products/multigov/guides/.pages new file mode 100644 index 000000000..cc8edf95d --- /dev/null +++ b/products/multigov/guides/.pages @@ -0,0 +1,6 @@ +title: Guides +nav: +- 'Deploy to EVM Chains': deploy-to-evm.md +- 'Deploy to Solana': deploy-to-solana.md +- 'Upgrade on EVM Chains': upgrade-evm.md +- 'Upgrade on Solana': upgrade-solana.md diff --git a/build/multigov/deploy-to-evm.md b/products/multigov/guides/deploy-to-evm.md similarity index 98% rename from build/multigov/deploy-to-evm.md rename to products/multigov/guides/deploy-to-evm.md index ad98f96ac..4bdec947c 100644 --- a/build/multigov/deploy-to-evm.md +++ b/products/multigov/guides/deploy-to-evm.md @@ -6,7 +6,7 @@ categories: MultiGov # Deploy MultiGov on EVM Chains -This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/build/multigov/){target=\_blank}. +This guide provodes instructions to set up and deploy the MultiGov governance system locally. Before diving into the technical deployment, ensure that MultiGov is the right fit for your project’s governance needs by following the steps for the [integration process](/docs/products/multigov/get-started/){target=\_blank}. Once your project is approved through the intake process and you’ve collaborated with the Tally team to tailor MultiGov to your requirements, use this guide to configure, compile, and deploy the necessary smart contracts across your desired blockchain networks. This deployment will enable decentralized governance across your hub and spoke chains. diff --git a/build/multigov/deploy-to-solana.md b/products/multigov/guides/deploy-to-solana.md similarity index 98% rename from build/multigov/deploy-to-solana.md rename to products/multigov/guides/deploy-to-solana.md index 78855bee5..4fc956d99 100644 --- a/build/multigov/deploy-to-solana.md +++ b/products/multigov/guides/deploy-to-solana.md @@ -6,7 +6,7 @@ categories: MultiGov # Deploy MultiGov on Solana -This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/learn/governance/architecture/){target=\_blank}. +This guide provides instructions on how to set up and deploy the **MultiGov Staking Program** on Solana. Before proceeding with the deployment, ensure that MultiGov aligns with your project's governance needs by reviewing the system [architecture](/docs/products/multigov/concepts/architecture/){target=\_blank}. Once your project setup is complete, follow this guide to configure, compile, and deploy the necessary Solana programs and supporting accounts. This deployment enables decentralized governance participation on Solana as a spoke chain within the MultiGov system. diff --git a/build/multigov/upgrade-evm.md b/products/multigov/guides/upgrade-evm.md similarity index 100% rename from build/multigov/upgrade-evm.md rename to products/multigov/guides/upgrade-evm.md diff --git a/build/multigov/upgrade-solana.md b/products/multigov/guides/upgrade-solana.md similarity index 100% rename from build/multigov/upgrade-solana.md rename to products/multigov/guides/upgrade-solana.md diff --git a/products/multigov/overview.md b/products/multigov/overview.md new file mode 100644 index 000000000..7b136d69c --- /dev/null +++ b/products/multigov/overview.md @@ -0,0 +1,56 @@ +--- +title: MultiGov Overview +description: Enable multichain governance with MultiGov. Create, vote, and execute DAO proposals securely across Wormhole supported networks. +categories: Multigov +--- + +# MultiGov Overview + +MultiGov is a multichain governance system that enables decentralized decision-making across multiple blockchain networks. Built on Wormhole messaging, it allows DAOs to manage proposals, voting, and execution from any connected chain without relying on a single hub or bridging assets. It empowers true multichain governance by aggregating voting power across chains and coordinating secure proposal execution. + +## Key Features + +MultiGov expands DAO governance across blockchains, increasing participation, improving security with Wormhole messaging, and enabling unified decision-making at scale. Key features include: + +- **Multichain governance**: Token holders can vote and execute proposals from any supported chain. +- **Hub-and-spoke model**: Proposals are created on a central hub chain and voted on from spoke chains, where governance tokens live. +- **Secure vote aggregation**: Vote weights are checkpointed and verified to prevent double voting. +- **Cross-chain proposal execution**: Approved proposals can be executed across multiple chains. +- **Flexible architecture**: Can integrate with any Wormhole-supported blockchain. +- **Upgradeable and extensible**: Supports upgrades across components while preserving vote history and system continuity. +- **Backed by Tally**: Proposal creation, voting, and execution are coordinated via [Tally](https://www.tally.xyz/get-started){target=\_blank}. + +## How It Works + +1. **Create proposal on hub chain**: Proposals are created on the hub chain, which manages the core governance logic, including vote aggregation and execution scheduling. +2. **Vote from spoke chains**: Token holders on spoke chains vote locally using `SpokeVoteAggregators`, with checkpoints tracking their voting power. +3. **Transmit votes via Wormhole**: Votes are securely sent to the hub using [VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}, ensuring message integrity and cross-chain verification. +4. **Aggregate and finalize on hub**: The hub chain receives votes from all spokes, tallies results, and finalizes the outcome once the voting period ends. +5. **Execute actions across chains**: Upon approval, proposals can trigger execution on one or more chains, again using [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} to deliver commands. + + + +## Use Cases + +- **Cross-Chain Treasury Management** + + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Vote on treasury actions from any supported chain. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Transmit proposal execution to target chains. + - [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank}: Optionally move assets. + +- **Coordinated Protocol Upgrades Across Chains** + + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Create a unified proposal to upgrade contracts across networks. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Send upgrade instructions as VAAs and deliver execution payloads to target chains. + +- **Progressive Decentralization for Multichain DAOs** + + - [**MultiGov**](/docs/products/multigov/get-started/){target=\_blank}: Extend governance to new chains while preserving coordination. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch on-chain vote weights from remote spokes. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Aggregate results and execute actions via the hub. + +## Next Steps + +Follow these steps to get started with MultiGov: + +[timeline(wormhole-docs/.snippets/text/products/multigov/multigov-timeline.json)] diff --git a/products/multigov/tutorials/.pages b/products/multigov/tutorials/.pages new file mode 100644 index 000000000..7ffdc370f --- /dev/null +++ b/products/multigov/tutorials/.pages @@ -0,0 +1,3 @@ +title: Tutorials +nav: +- 'Create a Treasury Management Proposal': treasury-proposal.md diff --git a/tutorials/multigov/treasury-proposal.md b/products/multigov/tutorials/treasury-proposal.md similarity index 100% rename from tutorials/multigov/treasury-proposal.md rename to products/multigov/tutorials/treasury-proposal.md diff --git a/products/native-token-transfers/.pages b/products/native-token-transfers/.pages new file mode 100644 index 000000000..2981eb884 --- /dev/null +++ b/products/native-token-transfers/.pages @@ -0,0 +1,9 @@ +title: Native Token Transfers +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- configuration +- concepts +- 'FAQs': faqs.md +- reference diff --git a/products/native-token-transfers/concepts/.pages b/products/native-token-transfers/concepts/.pages new file mode 100644 index 000000000..1e4ae1c43 --- /dev/null +++ b/products/native-token-transfers/concepts/.pages @@ -0,0 +1,4 @@ +title: Concepts +nav: +- 'Architecture': architecture.md +- 'Security': security.md \ No newline at end of file diff --git a/learn/transfers/native-token-transfers/architecture.md b/products/native-token-transfers/concepts/architecture.md similarity index 95% rename from learn/transfers/native-token-transfers/architecture.md rename to products/native-token-transfers/concepts/architecture.md index d9f0ff37a..f04d3693b 100644 --- a/learn/transfers/native-token-transfers/architecture.md +++ b/products/native-token-transfers/concepts/architecture.md @@ -8,7 +8,6 @@ categories: NTT, Transfer The Native Token Transfers (NTT) architecture within the Wormhole ecosystem offers a robust framework for secure and efficient token transfers across multiple blockchains. This architecture relies on the manager and transceiver core components that work together to manage cross-chain communication and token operations complexities. -For the technical implementations of the functions, refer to the [Managers and Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/){target=\_blank} page. ## System Components @@ -50,10 +49,10 @@ How it works: 2. It quotes delivery fees, handles cross-chain message relaying, and verifies delivery to ensure tokens are safely transferred 3. For each message, the transceiver coordinates with managers, ensuring only authorized transfers are processed on the destination chain -![NTT architecture diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-1.webp) +![NTT architecture diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-1.webp) !!! note - [Learn more](/docs/learn/transfers/native-token-transfers/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. + [Learn more](/docs/products/native-token-transfers/concepts/architecture/#lifecycle-of-a-message){target=\_blank} about the architecture of Native Token Transfers message lifecycles. #### Custom Transceivers @@ -61,7 +60,7 @@ The NTT framework supports advanced features such as custom transceivers for spe NTT has the flexibility to support custom message verification in addition to Wormhole Guardian message verification. Custom verifiers are implemented as transceiver contracts and can be protocol-specific or provided by other third-party attesters. Protocols can also configure the threshold of attestations required to mark a token transfer as valid — for example, 2/2, 2/3, 3/5. -![Custom Attestation with NTT diagram](/docs/images/learn/transfers/native-token-transfers/architecture/architecture-2.webp) +![Custom Attestation with NTT diagram](/docs/images/products/native-token-transfers/concepts/architecture/architecture-2.webp) The verifier performs checks based on predefined criteria and issues approval for transactions that meet these requirements. This approval is incorporated into the Wormhole message, ensuring that only transactions verified by both the Wormhole Guardian Network and the additional verifier are processed. The model includes an extra verifier in the bridging process, enhancing security and providing an added assurance of transaction integrity. diff --git a/learn/transfers/native-token-transfers/security.md b/products/native-token-transfers/concepts/security.md similarity index 100% rename from learn/transfers/native-token-transfers/security.md rename to products/native-token-transfers/concepts/security.md diff --git a/products/native-token-transfers/configuration/.pages b/products/native-token-transfers/configuration/.pages new file mode 100644 index 000000000..e54bd132d --- /dev/null +++ b/products/native-token-transfers/configuration/.pages @@ -0,0 +1,4 @@ +title: Configuration +nav: +- 'Access Control': 'access-control.md' +- 'Rate Limits': 'rate-limiting.md' \ No newline at end of file diff --git a/build/transfers/native-token-transfers/configuration/access-control.md b/products/native-token-transfers/configuration/access-control.md similarity index 100% rename from build/transfers/native-token-transfers/configuration/access-control.md rename to products/native-token-transfers/configuration/access-control.md diff --git a/build/transfers/native-token-transfers/configuration/rate-limiting.md b/products/native-token-transfers/configuration/rate-limiting.md similarity index 100% rename from build/transfers/native-token-transfers/configuration/rate-limiting.md rename to products/native-token-transfers/configuration/rate-limiting.md diff --git a/build/transfers/native-token-transfers/faqs.md b/products/native-token-transfers/faqs.md similarity index 85% rename from build/transfers/native-token-transfers/faqs.md rename to products/native-token-transfers/faqs.md index 800e30482..48faaddbc 100644 --- a/build/transfers/native-token-transfers/faqs.md +++ b/products/native-token-transfers/faqs.md @@ -8,9 +8,9 @@ categories: NTT, Transfer ## Do you have an example of how cross-chain lending can be implemented using Wormhole? -Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. +Yes, we have an example of cross-chain lending that leverages [Wormhole’s Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. In this example, collateral deposits (such as ETH on Ethereum) are bridged to a hub chain. Once the collateral is deposited, the borrowed assets, like wrapped BNB, are bridged to Binance Smart Chain. You can explore the full implementation in the [Wormhole Lending Examples repository](https://github.com/wormhole-foundation/example-wormhole-lending){target=_blank} on GitHub. -Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/learn/transfers/native-token-transfers/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. +Alternatively, you can also implement cross-chain lending using [Wormhole’s core messaging](/docs/products/messaging/overview/){target=\_blank} instead of the Token Bridge, which avoids the limitations imposed by governor limits. ETH would be custodied on Ethereum, and BNB on the Binance spoke during this setup. When a user deposits ETH on Ethereum, a core bridge message is sent to the hub for accounting purposes. The hub then emits a message that can be redeemed on Binance to release the BNB. This approach allows for more direct asset control across chains while reducing reliance on Token Bridge limits. ## What causes the "No protocols registered for Evm" error in Wormhole SDK? @@ -127,10 +127,35 @@ To begin transferring tokens to a chain in burning mode when no tokens are locke ## Is there a way to use NTT tokens with chains that don't currently support NTT? -Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank}. For example: +Yes. NTT tokens can be used with chains that do not support NTT by leveraging the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}. For example: - **Wrapped token scenario** - a token, such as the W token, can be bridged to non-NTT networks using the Token Bridge. When the token is bridged to a chain like Sui, a wrapped version of the token is created (e.g., Wrapped W token) - **Unwrapping requirement** - tokens bridged using the Token Bridge cannot be directly transferred to NTT-supported chains. To transfer them, they must first be unwrapped on the non-NTT chain and then transferred via the appropriate mechanism - **Messaging consistency** - the Token Bridge exclusively uses Wormhole messaging, ensuring consistent communication across all chains, whether or not they support NTT -This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. \ No newline at end of file +This approach ensures interoperability while maintaining the integrity of the token's cross-chain movement. + +## How can I update my NTT CLI version? + +To update an existing NTT CLI installation, run the following command in your terminal: + +```bash +ntt update +``` + +NTT CLI installations and updates will always pick up the latest tag with name vX.Y.Z+cli and verify that the underlying commit is included in main. + +For local development, you can update your CLI version from a specific branch or install from a local path. + +To install from a specific branch, run: + +```bash +ntt update --branch foo +``` + +To install locally, run: +```bash +ntt update --path path/to/ntt/repo +``` + +Git branch and local installations enable a fast iteration loop as changes to the CLI code will immediately be reflected in the running binary without having to run any build steps. \ No newline at end of file diff --git a/products/native-token-transfers/get-started.md b/products/native-token-transfers/get-started.md new file mode 100644 index 000000000..3adfed3ce --- /dev/null +++ b/products/native-token-transfers/get-started.md @@ -0,0 +1,195 @@ +--- +title: Get Started with NTT +description: NTT enables cross-chain token movement without wrapping. Install the CLI, deploy test tokens, and scaffold a project to integrate NTT into your app. +categories: NTT, Transfer +--- + +# Get Started with NTT + +## Introduction + +The [Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview){target=\_blank} framework enables seamless cross-chain token movement without wrapping or liquidity pools. This guide shows you how to install the NTT CLI, which is used to configure and deploy native token contracts, and scaffold your first project for deployment on testnet or mainnet. + +If you are looking for a no-code experience to deploy on mainnet, you can explore the [NTT Launchpad](https://ntt.wormhole.com){target=\_blank}. + +## Prerequisites + +Before you begin, make sure you have: + +- [Node.js and npm installed](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} +- [Bun installed](https://bun.sh/){target=\_blank} +- A wallet private key with tokens on supported chains +- ERC-20 or SPL tokens already deployed on the source and destination chains + +## Don’t Have a Token Yet? + +To use NTT, you must have a token already deployed on the source and destination chains. If you don’t have one, follow the quick guides below to deploy a basic test token. + +???- interface "Deploy an ERC-20 Token on EVM" + Use the [example NTT token repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank} to deploy a basic ERC-20 token contract on testnet. + + 1. **Install Foundry** - install the [Forge CLI](https://book.getfoundry.sh/getting-started/installation){target=\_blank} + + 2. **Clone the repository** – fetch the example contract repository + + ```bash + git clone https://github.com/wormhole-foundation/example-ntt-token.git + cd example-ntt-token + ``` + + 3. **Deploy the token contract** – deploy to testnet with your preferred name, symbol, minter, and owner addresses + + ```bash + forge create --broadcast \ + --rpc-url INSERT_RPC_URL \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + src/PeerToken.sol:PeerToken \ + --constructor-args "INSERT_TOKEN_NAME" "INSERT_TOKEN_SYMBOL" INSERT_MINTER_ADDRESS INSERT_OWNER_ADDRESS + ``` + + 4. **Mint tokens** – send tokens to your address + + ```bash + cast send INSERT_TOKEN_ADDRESS \ + "mint(address,uint256)" \ + INSERT_RECIPIENT_ADDRESS \ + INSERT_AMOUNT_IN_WEI \ + --private-key INSERT_YOUR_PRIVATE_KEY \ + --rpc-url INSERT_RPC_URL + ``` + + !!! note + This token uses 18 decimals by default. All minting values must be specified in `wei` (1 token = 10^18). + + +???- interface "Create and Mint SPL Tokens" + This section walks you through generating a Solana wallet, deploying an SPL token, creating a token account, and minting tokens. + + 1. **Generate a Solana key pair** - run the following command to create a new wallet: + + ```bash + solana-keygen grind --starts-with w:1 --ignore-case + ``` + + 2. **Set Solana configuration** - configure the Solana CLI to use the generated key pair using the following command: + + ```bash + solana config set --keypair INSERT_PATH_TO_KEYPAIR_JSON + ``` + + 3. **Select an RPC URL** - configure Solana to use the appropriate network using one of the following commands: + + === "Mainnet" + ```bash + solana config set -um + ``` + + === "Testnet" + ```bash + solana config set -ut + ``` + + === "Devnet" + ```bash + solana config set -ud + ``` + + 4. **Fund your wallet** - ensure you have enough SOL to create a token. If deploying on devnet, request an airdrop with the following commands: + + ```bash + solana airdrop 2 + solana balance + ``` + + 5. **Install SPL Token CLI** - install or update the required [CLI tool](https://spl.solana.com/token){target=\_blank} + + ```bash + cargo install spl-token-cli + ``` + + 6. **Create a new SPL token** - initialize the token on Solana + + ```bash + spl-token create-token + ``` + + 7. **Create a token account** - generate an account to hold the token + + ```bash + spl-token create-account INSERT_TOKEN_ADDRESS + ``` + + 8. **Mint tokens** - send 1000 tokens to the created account + + ```bash + spl-token mint INSERT_TOKEN_ADDRESS 1000 + ``` + + !!! note + NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. + +## Install NTT CLI + +
+ +The NTT CLI is recommended to deploy and manage your cross-chain token configuration. + +1. Run the installation command in your terminal: + + ```bash + curl -fsSL https://raw.githubusercontent.com/wormhole-foundation/native-token-transfers/main/cli/install.sh | bash + ``` + +2. Verify the NTT CLI is installed: + + ```bash + ntt --version + ``` + +## Initialize a New NTT Project + +1. Once the CLI is installed, scaffold a new project by running: + + ```bash + ntt new my-ntt-project + cd my-ntt-project + ``` + +2. Initialize a new `deployment.json` file specifying the network: + + === "Mainnet" + ```bash + ntt init Mainnet + ``` + + === "Testnet" + ```bash + ntt init Testnet + ``` + + After initialization, the `deployment.json` file contains your NTT configuration and starts with the selected network. + + === "Mainnet" + ```json + { + "network": "Mainnet", + "chains": {} + } + ``` + + === "Testnet" + ```json + { + "network": "Testnet", + "chains": {} + } + ``` + +In the deployment steps, you will add your supported chains, their token addresses, deployment modes, and any custom settings. + +## Next Steps + +You have scaffolded your NTT project and initialized the configuration file. Next, follow the appropriate guide below to configure your supported chains and deploy NTT contracts: + +- [Deploy to EVM](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank}: Deploy NTT on EVM-compatible chains. +- [Deploy to Solana](/docs/products/native-token-transfers/guides/deploy-to-solana/){target=\_blank}: Deploy NTT on Solana. diff --git a/products/native-token-transfers/guides/.pages b/products/native-token-transfers/guides/.pages new file mode 100644 index 000000000..69ca6f893 --- /dev/null +++ b/products/native-token-transfers/guides/.pages @@ -0,0 +1,7 @@ +title: Deployment Guides +nav: +- 'Deploy to EVM Chains': deploy-to-evm.md +- 'Deploy to EVM Chains via Launchpad': evm-launchpad.md +- 'Deploy to Solana': deploy-to-solana.md +- 'Troubleshoot Your Deployment': troubleshoot.md +- 'Post Deployment': post-deployment.md \ No newline at end of file diff --git a/products/native-token-transfers/guides/deploy-to-evm.md b/products/native-token-transfers/guides/deploy-to-evm.md new file mode 100644 index 000000000..b1527c0b6 --- /dev/null +++ b/products/native-token-transfers/guides/deploy-to-evm.md @@ -0,0 +1,143 @@ +--- +title: Native Token Transfers EVM Deployment +description: Deploy and configure Wormhole’s Native Token Transfers (NTT) for EVM chains, including setup, token compatibility, mint/burn modes, and CLI usage. +categories: NTT, Transfer +--- + +# Deploy Native Token Transfers (NTT) to EVM Chains + +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of ERC-20 tokens on [supported EVM-compatible chains](/docs/products/reference/supported-networks/#ntt){target=\_blank} using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. + +This guide walks you through deploying NTT on EVM chains, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. + +## Deploy Your Token and Ensure Compatibility + +If you still need to do so, deploy the token contract to the destination or spoke chains. + +### Requirements for Token Deployment + +Wormhole’s NTT framework supports two [deployment models](/docs/products/native-token-transfers/overview#deployment-models){target=\_blank}: burn-and-mint and hub-and-spoke. **Both require an ERC-20 token (new or existing).** + +??? interface "Burn-and-Mint" + + Tokens must implement the following non-standard ERC-20 functions: + + - `burn(uint256 amount)` + - `mint(address account, uint256 amount)` + + These functions aren't part of the standard ERC-20 interface. Refer to the [`INttToken` interface](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} for all required functions, errors, and events. + + ??? interface "`INttToken` Interface" + ```solidity + --8<-- 'code/products/native-token-transfers/guides/deploy-to-evm/INttToken.sol' + ``` + + You’ll also need to set mint authority to the relevant `NttManager` contract. Example deployment scripts are available in the [`example-ntt-token` GitHub repository](https://github.com/wormhole-foundation/example-ntt-token){target=\_blank}. + +??? interface "Hub-and-Spoke Mode" + + Tokens only need to be ERC-20 compliant. The hub chain serves as the source of truth for supply consistency, while only spoke chains need to support minting and burning. For example, if Ethereum is the hub and Polygon is a spoke: + + - Tokens are locked on Ethereum + - Tokens are minted or burned on Polygon + + This setup maintains a consistent total supply across all chains. + +## NTT Manager Deployment Parameters + +This table compares the configuration parameters available when deploying the NTT Manager using the CLI versus a manual deployment with a Forge script. It highlights which options are configurable via each method, whether values are auto-detected or hardcoded, and includes additional comments to help guide deployment decisions. + +|
Parameter
| Forge Script | CLI | Both | Comments | +|-------------------------|------------------------|-------------------------------------|--------|----------------------------------------------| +| `token` | Input | `--token
` | Yes | | +| `mode` | Input | `--mode ` | Yes | Key decision: hub-and-spoke or mint-and-burn | +| `wormhole` | Input | Auto-detected via SDK/`ChainContext` | Similar| | +| `wormholeRelayer` | Input | Auto-detected via on-chain query/SDK| Similar| | +| `specialRelayer` | Input | Not exposed | No | Take into consideration if using custom relaying. Not recommended | +| `decimals` | Input, overridable | Auto-detected via token contract, not overridable | Similar | | +| `wormholeChainId` | Queried from Wormhole contract | `--chain` (network param, mapped internally) | Yes | | +| `rateLimitDuration` | Hardcoded (`86400`) | Hardcoded (`86400`) | Yes | Rate limit duration. A day is normal but worth deciding | +| `shouldSkipRatelimiter` | Hardcoded (`false`) | Hardcoded (`false`) | Yes | If rate limit should be disabled (when the manager supports it) | +| `consistencyLevel` | Hardcoded (`202`) | Hardcoded (`202`) | Yes | `202` (finalized) is the standard — lower is not recommended | +| `gasLimit` | Hardcoded (`500000`) | Hardcoded (`500000`) | Yes | | +| `outboundLimit` | Computed | Auto-detected/Hardcoded | Similar| Relative to rate limit | + + +## Deploy NTT + +Before deploying NTT contracts on EVM chains, you need to scaffold a project and initialize your deployment configuration. + +???- interface "Install the NTT CLI and Scaffold a New Project" + + --8<-- 'text/products/native-token-transfers/guides/install-ntt-project.md' + +Once you've completed those steps, return here to proceed with adding your EVM chains and deploying contracts. + +Ensure you have set up your environment correctly: + +```bash +export ETH_PRIVATE_KEY=INSERT_PRIVATE_KEY +``` + +Add each chain you'll be deploying to. The following example demonstrates configuring NTT in burn-and-mint mode on Ethereum Sepolia and Arbitrum Sepolia: + +```bash +--8<-- 'code/products/native-token-transfers/guides/deploy-to-evm/initialize.txt' +``` + +While not recommended, you can pass the `-skip-verify` flag to the `ntt add-chain` command if you want to skip contract verification. + +The `ntt add-chain` command takes the following parameters: + +- Name of each chain +- Version of NTT to deploy (use `--latest` for the latest contract versions) +- Mode (either `burning` or `locking`) +- Your token contract address + +The NTT CLI prints detailed logs and transaction hashes, so you can see exactly what's happening under the hood. + +## Configure NTT + +The NTT CLI takes inspiration from [git](https://git-scm.com/){target=\_blank}. You can run: + +- `ntt status` - checks whether your `deployment.json` file is consistent with what is on-chain +- `ntt pull` - syncs your `deployment.json` file with the on-chain configuration and set up rate limits with the appropriate number of decimals, depending on the specific chain. For example: + + For Solana, the limits are set with 9 decimal places: + ```json + "inbound": { + "Sepolia": "1000.000000000" // inbound limit from Sepolia to Solana + } + ``` + + For Sepolia (Ethereum Testnet), the limits are set with 18 decimal places: + ```json + "inbound": { + "Solana": "1000.000000000000000000" // inbound limit from Solana to Sepolia + } + ``` + + This initial configuration ensures that the rate limits are correctly represented for each chain's token precision + +- `ntt push` - syncs the on-chain configuration with local changes made to your `deployment.json` file + +After you deploy the NTT contracts, ensure that the deployment is properly configured and your local representation is consistent with the actual on-chain state by running `ntt status` and following the instructions shown on the screen. + +## Set Token Minter to NTT Manager + +The final step in the deployment process is to set the NTT Manager as a minter of your token on all chains you have deployed to in `burning` mode. When performing a hub-and-spoke deployment, it is only necessary to set the NTT Manager as a minter of the token on each spoke chain. + +!!! note + The required NTT Manager address can be found in the `deployment.json` file. + +- If you followed the [`INttToken`](https://github.com/wormhole-foundation/native-token-transfers/blob/main/evm/src/interfaces/INttToken.sol){target=\_blank} interface, you can execute the `setMinter(address newMinter)` function + ```json + cast send $TOKEN_ADDRESS "setMinter(address)" $NTT_MANAGER_ADDRESS --private-key $ETH_PRIVATE_KEY --rpc-url $YOUR_RPC_URL + ``` + +- If you have a custom process to manage token minters, you should now follow that process to add the corresponding NTT Manager as a minter + +By default, NTT transfers to EVM blockchains support automatic relaying via the Wormhole relayer, which doesn't require the user to perform a transaction on the destination chain to complete the transfer. + +!!!important + To proceed with testing and find integration examples, check out the [NTT Post Deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} page. \ No newline at end of file diff --git a/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md b/products/native-token-transfers/guides/deploy-to-solana.md similarity index 75% rename from build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md rename to products/native-token-transfers/guides/deploy-to-solana.md index a3389b4f7..eabc2c12c 100644 --- a/build/transfers/native-token-transfers/deployment-process/deploy-to-solana.md +++ b/products/native-token-transfers/guides/deploy-to-solana.md @@ -6,11 +6,9 @@ categories: NTT, Transfer # Deploy Native Token Transfers on Solana -[Native Token Transfers (NTT)](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. +[Native Token Transfers (NTT)](/docs/products/native-token-transfers/overview/){target=\_blank} enable seamless multichain transfers of SPL tokens on Solana using Wormhole's messaging protocol. Instead of creating wrapped tokens, NTT allows native assets to move across chains while maintaining their original properties. -This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. - -By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. +This guide walks you through deploying NTT on Solana, including setting up dependencies, configuring token compatibility, and using the NTT CLI to deploy in hub-and-spoke or burn-and-mint mode. By the end, a fully deployed NTT will be set up, allowing your token to transfer between Solana and other supported chains. ## Prerequisites @@ -97,54 +95,39 @@ Deploying NTT with the CLI on Solana follows a structured process: !!! note NTT versions `>=v2.0.0+solana` support SPL tokens with [transfer hooks](https://spl.solana.com/transfer-hook-interface){target=\_blank}. -2. **Choose your [deployment model](/docs/learn/transfers/native-token-transfers/deployment/){target=\_blank}**: +2. **Choose your deployment model**: - - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required - - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program + - **Hub-and-spoke** - tokens are locked on a hub chain and minted on destination spoke chains. Since the token supply remains controlled by the hub chain, no changes to the minting authority are required + - **Burn-and-mint** - tokens are burned on the source chain and minted on the destination chain. This requires transferring the SPL token's minting authority to the Program Derived Address (PDA) controlled by the NTT program 3. **Deploy and configure NTT** - use the NTT CLI to initialize and deploy the NTT program, specifying your SPL token and deployment mode +![Solana NTT deployment diagram](/docs/images/products/native-token-transfers/guides/solana/ntt-solana-guide-1.webp) + Following this process, your token will fully integrate with NTT, enabling seamless transfers between Solana and other chains. -By default, NTT transfers to Solana require manual [relaying](/docs/learn/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. +By default, NTT transfers to Solana require manual [relaying](/docs/protocol/infrastructure/relayer/){target=\_blank}, meaning users must complete a transaction on Solana to finalize the transfer. For automatic relaying, where transactions are completed without user intervention, additional setup is required. [Contact Wormhole contributors](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank} to enable automatic relaying support for your deployment. ## Set Up NTT To integrate your token with NTT on Solana, you must initialize the deployment and configure its parameters. This process sets up the required contracts and may generate key pairs if they don't exist. These key pairs are used to sign transactions and authorize actions within the NTT deployment. -The [NTT CLI](/docs/build/transfers/native-token-transfers/deployment-process/installation/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: - -1. **Create a new NTT project** - set up a deployment workspace - - ```bash - ntt new INSERT_PROJECT_NAME - cd INSERT_PROJECT_NAME - ``` - -2. **Initialize the deployment** - generate a `deployment.json` file with your deployment settings - - === "Mainnet" +The [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank} manages deployments, configures settings, and interacts with the NTT system. Follow these steps to set up NTT using the CLI tool: - ```bash - ntt init Mainnet - ``` +???- interface "Install the NTT CLI and Scaffold a New Project" - === "Testnet" - - ```bash - ntt init Testnet - ``` -!!! note - Testnet deployment settings work for both Solana Testnet and Devnet networks. + --8<-- 'text/products/native-token-transfers/guides/install-ntt-project.md' + !!! note + Testnet deployment settings work for both Solana Testnet and Devnet networks. ### Generate an NTT Program Key Pair Create a unique key pair for the NTT program: - - ```bash - solana-keygen grind --starts-with ntt:1 --ignore-case - ``` + +```bash +solana-keygen grind --starts-with ntt:1 --ignore-case +``` ### Set Mint Authority @@ -171,7 +154,7 @@ Follow these steps to set the mint authority using the NTT CLI: ## Deploy and Configure NTT !!! warning - If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/build/transfers/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. + If deploying to Solana mainnet, you must use a custom RPC. See how to [set it up in your project](/docs/products/native-token-transfers/faqs/#how-can-i-specify-a-custom-rpc-for-ntt){target=\_blank} using an `overrides.json` file. For optimal performance, consider using a staked RPC connection from either Triton or Helius. After setting up your deployment, finalize the configuration and deploy the NTT program on Solana by following these steps: @@ -237,7 +220,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i After deploying NTT on Solana, deploy and integrate it on EVM chains to enable seamless multichain transfers. - [:custom-arrow: Deploy NTT on EVM](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/){target=\_blank} + [:custom-arrow: Deploy NTT on EVM Chains](/docs/products/native-token-transfers/guides/deploy-to-evm/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Test Your Deployment** @@ -245,7 +228,7 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Follow the NTT Post Deployment Guide for integration examples and testing instructions. - [:custom-arrow: Test Your NTT deployment](/docs/build/transfers/native-token-transfers/deployment-process/post-deployment/){target=\_blank} + [:custom-arrow: Test Your NTT deployment](/docs/products/native-token-transfers/guides/post-deployment/){target=\_blank} - :octicons-tools-16:{ .lg .middle } **Add NTT to Your dApp** @@ -253,7 +236,15 @@ Failed Solana deployments don't result in lost SOL. Instead, SOL may be locked i Configure Wormhole Connect, a plug-and-play bridging UI, to enable multichain transfers for your token. - [:custom-arrow: Use Connect to Integrate NTT](/docs/build/transfers/connect/){target=\_blank} + [:custom-arrow: Use Connect to Integrate NTT](/docs/products/connect/overview/){target=\_blank} + +- :octicons-question-16:{ .lg .middle } **View FAQs** + + --- + + Find answers to common questions about NTT. + + [:custom-arrow: View FAQs](/docs/products/native-token-transfers/faqs){target=\_blank} - :octicons-question-16:{ .lg .middle } **View FAQs** diff --git a/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md b/products/native-token-transfers/guides/evm-launchpad.md similarity index 63% rename from build/transfers/native-token-transfers/deployment-process/evm-launchpad.md rename to products/native-token-transfers/guides/evm-launchpad.md index 526014761..97b543fb6 100644 --- a/build/transfers/native-token-transfers/deployment-process/evm-launchpad.md +++ b/products/native-token-transfers/guides/evm-launchpad.md @@ -43,8 +43,8 @@ The NTT Launchpad currently supports deployments on the following mainnet chains Once ready, choose an option to proceed: - - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token) - deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains - - [**Expand Your Existing Token**](#expand-your-existing-token) - if you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract + - [**Launch a Cross-Chain Token**](#launch-a-cross-chain-token): Deploy a brand-new token that is NTT-ready from day one, enabling seamless transfers across multiple blockchains. + - [**Expand Your Existing Token**](#expand-your-existing-token): If you already have a token deployed on different chains, integrate it with NTT to enable NTT without modifying its original contract. ## Launch a Cross-Chain Token @@ -52,11 +52,11 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Launch a Cross-Chain Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-2.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-2.webp) 3. Set the token details: 1. Select the **home network** from the dropdown menu @@ -65,22 +65,22 @@ Deploy a new NTT-compatible token that can be transferred across multiple chains 4. Provide the **initial supply** 5. To the token details, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-3.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-3.webp) 4. Select the deployment chains: 1. The home network where your token will be deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-4.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-4.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -92,33 +92,33 @@ Expand an existing token to support NTT across multiple chains. This process int 1. Open the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank}, connect your wallet, and click **Get Started** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-1.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-1.webp) 2. Select **Expand Your Existing Token** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-7.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-7.webp) 3. Enter the token details: 1. Choose the home network where your token is already deployed (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 3. To continue, click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-8.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-8.webp) 4. Select the chains to deploy your token to: 1. The home network where your token is already deployed will be populated (e.g., Optimism) 2. Choose any additional chains to deploy your token to (e.g., Base) 1. Click **Next** - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-9.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-9.webp) 5. To deploy on the first chain (Optimism), click on **Deploy**; if prompted, switch your wallet to the correct network and confirm the transaction - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-5.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-5.webp) 6. Once deployed, you can view the transaction in a block explorer and add the token to your wallet - ![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-6.webp) + ![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-6.webp) 7. Repeat the previous step to deploy the token on the second chain (Base). The supply of tokens on Base will be zero since the tokens were all minted on Optimism in the previous step @@ -128,7 +128,7 @@ Expand an existing token to support NTT across multiple chains. This process int To access the **Dashboard** from the [Launchpad home page](https://ntt.wormhole.com/){target=\_blank}, click on **Manage Deployment**. Here, you can view deployment status, monitor supply across chains, and configure transfer settings. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-10.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-10.webp) The dashboard provides a high-level view of your token across all deployed chains, including: @@ -136,7 +136,7 @@ The dashboard provides a high-level view of your token across all deployed chain - Supply distribution visualization - List of deployed chains, including inbound and outbound transfer limits, which can be modified in [**Settings**](#settings) -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-11.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-11.webp) ## Settings @@ -148,38 +148,38 @@ Use the drop-down menu at the top to select the chain you want to configure. The From this section, you can also: - - **Pause the token** – temporarily turn off transfers on the selected chain - - **Deploy to a new chain** – expand your token by deploying it to an additional chain + - **Pause the token**: Temporarily turn off transfers on the selected chain. + - **Deploy to a new chain**: Expand your token by deploying it to an additional chain. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-12.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-12.webp) ### Role Management -This section displays key [roles](/docs/build/transfers/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. +This section displays key [roles](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} involved in token governance. You can view and modify these roles by selecting a new address and confirming the update. - - **Manager’s Owner** – the owner through the `NTTOwner` proxy - - **Pauser** – the address authorized to pause transfers + - **Manager’s Owner**: The owner through the `NTTOwner` proxy. + - **Pauser**: The address authorized to pause transfers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-13.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-13.webp) ### Security Threshold -Determine and update how transceivers interact with the token. [Transceivers](/docs/build/transfers/native-token-transfers/managers-transceivers/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. +Determine and update how transceivers interact with the token. [Transceivers](/docs/products/native-token-transfers/concepts/architecture/#transceivers){target=\_blank} route NTT transfers between blockchains, ensuring tokens are correctly sent and received across networks. A higher transceiver threshold increases security by requiring more approvals before processing a transfer, but it may also slow down transactions. A lower threshold allows faster transfers but reduces redundancy in message verification. - - **Registered Transceivers** – displays the number of registered transceivers and their addresses - - **Transceivers Threshold** – a configurable value that must be less than or equal to the number of transceivers + - **Registered Transceivers**: Displays the number of registered transceivers and their addresses. + - **Transceivers Threshold**: A configurable value that must be less than or equal to the number of transceivers. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-14.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-14.webp) ### Peer Chains Limits Define the transfer restrictions for each connected network. You can adjust: - - **Sending Limits** – the maximum amount of tokens that can be sent from the home chain - - **Receiving Limits** – the maximum amount of tokens that can be received for each of the supported peer chains + - **Sending Limits**: The maximum amount of tokens that can be sent from the home chain. + - **Receiving Limits**: The maximum amount of tokens that can be received for each of the supported peer chains. Enter a new value to adjust limits and click **Update**. The changes will take effect immediately. -![](/docs/images/build/transfers/native-token-transfers/deployment-process/evm-launchpad/ntt-launchpad-15.webp) +![](/docs/images/products/native-token-transfers/guides/evm-launchpad/ntt-launchpad-15.webp) diff --git a/build/transfers/native-token-transfers/deployment-process/post-deployment.md b/products/native-token-transfers/guides/post-deployment.md similarity index 56% rename from build/transfers/native-token-transfers/deployment-process/post-deployment.md rename to products/native-token-transfers/guides/post-deployment.md index f2a25e135..72b36d59c 100644 --- a/build/transfers/native-token-transfers/deployment-process/post-deployment.md +++ b/products/native-token-transfers/guides/post-deployment.md @@ -9,9 +9,9 @@ categories: NTT, Transfer To offer the best user experience and ensure the most robust deployment, Wormhole contributors recommend the following after you have deployed Native Token Transfers (NTT): - Implement a robust testing plan for your multichain token before launching -- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/build/transfers/native-token-transfers/configuration/){target=\_blank} for more details on ownership and rate limits -- Consider a streamlined, customizable frontend such as [Wormhole Connect](/docs/build/transfers/connect/){target=\_blank} for an optimized user experience -- Alternatively, the [Wormhole TypeScript SDK](/docs/build/toolkit/typescript-sdk/){target=\_blank} allows for a direct integration into your infrastructure +- Ensure comprehensive, documented security measures are followed for custody of contract ownership, control of keys, and access control roles. Check the [NTT configuration](/docs/products/native-token-transfers/configuration/access-control/){target=\_blank} for more details on ownership and rate limits +- Consider a streamlined, customizable frontend such as [Connect](/docs/products/connect/overview/){target=\_blank} for an optimized user experience +- Alternatively, the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank} allows for a direct integration into your infrastructure - Ensure ecosystem actors such as block explorers, automated security tools (such as BlockAid and Blowfish), and wallets (such as MetaMask, Backpack, and Phantom) are aware of your multichain deployment and that it is labeled appropriately - Monitor and maintain your multichain deployment @@ -21,6 +21,20 @@ By default, NTT transfers to Solana require manual relaying, meaning that after This step ensures that tokens are properly minted or unlocked on Solana and prevents unauthorized claims. +## Post-Deployment Settings + +The following table outlines post-deployment settings available on the NTT Manager contract. These allow you to update roles, pause activity, and adjust transfer limits—useful for upgrades, incident response, or protocol tuning after initial deployment. + +| Setting | Effect | +|-------------------------|------------------------------------------| +| `pause` | Pauses the manager | +| `unpause` | Unpauses the manager | +| `setOwner` | Changes the manager owner | +| `setPauser` | Changes the pauser role | +| `setOutboundLimit` | Sets outbound transfer limit | +| `setInboundLimit` | Sets inbound transfer limit (per chain) | +| `setTransceiverPauser ` | Changes pauser for a transceiver | + ## Where to Go Next
@@ -29,7 +43,7 @@ This step ensures that tokens are properly minted or unlocked on Solana and prev --- - Check out an example project that uses a Vite-React TypeScript application and integrates it with Wormhole Connect, a customizable widget for cross-chain asset transfers. + Check out an example project that uses a Vite-React TypeScript application and integrates it with Connect, a customizable widget for cross-chain asset transfers. [:custom-arrow: Explore the NTT Connect demo](https://github.com/wormhole-foundation/demo-ntt-connect) diff --git a/build/transfers/native-token-transfers/deployment-process/troubleshooting.md b/products/native-token-transfers/guides/troubleshoot.md similarity index 86% rename from build/transfers/native-token-transfers/deployment-process/troubleshooting.md rename to products/native-token-transfers/guides/troubleshoot.md index c5778cb52..cc16efa19 100644 --- a/build/transfers/native-token-transfers/deployment-process/troubleshooting.md +++ b/products/native-token-transfers/guides/troubleshoot.md @@ -4,19 +4,19 @@ description: Resolve common issues in NTT deployment with this troubleshooting g categories: NTT, Transfer --- -# Troubleshooting NTT Deployment +# Troubleshoot Your NTT Deployment If you encounter issues during the NTT deployment process, check the following common points: -- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#install-dependencies){target=\_blank} +- **Solana and Anchor versions** - ensure you are using the expected versions of Solana and Anchor as outlined in the [deployment page](/docs/products/native-token-transfers/guides/deploy-to-solana/#install-dependencies){target=\_blank} - [Solana](https://docs.solanalabs.com/cli/install){target=\_blank} **`{{ ntt.solana_cli_version }}`** - [Anchor](https://www.anchor-lang.com/docs/installation){target=\_blank} **`{{ ntt.anchor_version }}`** - **Token compliance on EVM** - verify that your token is an ERC20 token on the EVM chain - **Mint authority transfer** - - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section - - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details -- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-solana/#configure-ntt){target=\_blank} section -- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/build/transfers/native-token-transfers/deployment-process/deploy-to-evm/#configure-ntt){target=\_blank} + - **For burn or spoke tokens on Solana** - ensure the token mint authority was transferred as described in the [set SPL Token Mint Authority](/docs/products/native-token-transfers/guides/deploy-to-solana/#set-spl-token-mint-authority){target=\_blank} section + - **For EVM tokens** - confirm the token minter was set to the NTT Manager. Refer to the [set Token Minter to NTT Manager](/docs/products/native-token-transfers/guides/deploy-to-evm/#set-token-minter-to-ntt-manager){target=\_blank} section for details +- **Decimal configuration** - run `ntt pull` to correctly configure the decimals in your `deployment.json` file. More details in the [configure NTT](/docs/products/native-token-transfers/guides/deploy-to-solana/#configure-ntt){target=\_blank} section +- **Rate limit configuration** - increase your rate limits to a value greater than zero. A rate limit of zero can cause transactions to get stuck. Learn more on how to [configure rate limits](/docs/products/native-token-transfers/guides/deploy-to-evm/#configure-ntt){target=\_blank} - **Docker environment based on Ubuntu 20.04 with all dependencies required for Wormhole NTT CLI development** - run `docker compose up -d` to start the container in your terminal from the directory containing the `docker-compose.yml` file ???- interface "Dockerfile" diff --git a/products/native-token-transfers/overview.md b/products/native-token-transfers/overview.md new file mode 100644 index 000000000..f04579496 --- /dev/null +++ b/products/native-token-transfers/overview.md @@ -0,0 +1,79 @@ +--- +title: Native Token Transfers Overview +description: With Native Token Transfers, you can directly transfer a blockchain's native assets across various connected networks. +categories: NTT, Transfer +--- + +## Native Token Transfers Overview + +Native Token Transfers (NTT) provides an adaptable framework for transferring your native tokens across different blockchains. Unlike traditional wrapped assets, NTT maintains your token's native properties on every chain. This ensures that you retain complete control over crucial aspects, such as metadata, ownership, upgradeability, and custom features. + +## Key Features + +- **Control and customization**: Ensure ownership and configurable access controls, permissions, and thresholds, preventing unauthorized calls. +- **Advanced rate limiting**: Set rate limits per chain and period to prevent abuse, manage network congestion, and control deployments. +- **Global accountant**: Ensures the amount burned and transferred on chains never exceeds the amount of tokens minted. +- **No wrapped tokens**: Tokens are used directly within their native ecosystem, eliminating intermediary transfer steps. + + +## Deployment Models + +NTT offers two operational modes for your existing tokens: + +- **Hub-and-spoke**: Locks tokens on a central "hub" chain and mints equivalents on "spoke" chains, maintaining the total supply on the hub. It's ideal for integrating existing tokens onto new blockchains without altering their original contracts. +- **Burn-and-mint**: Burns tokens on the source chain and mints new ones on the destination, distributing the total supply across multiple chains. It's best suited for new token deployments or projects willing to upgrade existing contracts for a truly native multichain token. + +## Supported Token Standards + +Native Token Transfers (NTT) primarily support ERC-20 tokens, the most widely used standard for fungible assets on Ethereum and other EVM-compatible chains, including ERC-20 Burnable tokens, which can be burned on the source chain during cross-chain transfers when required. It also supports fungible SPL tokens on Solana for secure cross-chain transfers. + +The NttManager is a contract that oversees the secure and reliable transfer of native tokens across supported blockchains. It leverages the standard IERC20 interface and OpenZeppelin’s SafeERC20 library to interact with these tokens securely across chains. + +NTT does not currently support token standards like ERC-721 (non-fungible tokens), ERC-1155 (a multi-token standard), or SPL-based tokens, such as Metaplex NFTs. Support is currently limited to ERC-20 tokens. + +## Deployment Process + +Here's a breakdown of the key steps involved when deploying NTT: + +- **Prepare tokens**: Ensure your ERC-20 or SPL tokens are ready. +- **Choose deployment model**: Choose your cross-chain token model: either burn-and-mint or hub-and-spoke. +- **Choose deployment tool**: Use the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for EVM chains only) or the [NTT CLI](/docs/products/native-token-transfers/reference/cli-commands/){target=\_blank}. +- **Initialization**: Specify target chains and token details, and set up your CLI environment if using it. +- **Deploy contracts**: Deploy NTT Manager contracts to all selected chains, confirming transactions and covering gas fees. +- **Finalize configurations**: Grant minting authority, configure rate limits, establish peer manager connections, and assign administrative roles. +- **Monitor and maintain**: Verify deployment, monitor total supply with the [Global Accountant](/docs/products/native-token-transfers/concepts/security/#global-accountant){target=\_blank}, and adjust configurations as needed. + +## Use Cases + +- **Cross-Chain Swaps and Liquidity Aggregation** + + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transmits native assets across chains. + - [**Connect**](/docs/products/connect/overview/): Manages user-friendly asset transfers. + - [**Queries**](/docs/products/queries/overview/): Acquires real-time prices for optimal trade execution. + +- **Borrowing and Lending Across Chains** + + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Moves collateral as native assets. + - [**Messaging**](/docs/products/messaging/overview/): Propagates loan requests and liquidations across chains. + - [**Queries**](/docs/products/queries/overview/): Retrieves interest rates and asset prices in real-time. + +- **Gas Abstraction** + + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Facilitates native token conversion for gas payments. + - [**Messaging**](/docs/products/messaging/overview/): Sends gas fee payments across chains. + +- **Cross-Chain Payment Widgets** + + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Ensures direct, native asset transfers. + - [**Connect**](/docs/products/connect/overview/): Facilitates seamless payments in various tokens. + +- **Cross-Chain Staking** + + - [**Native Token Transfers**](/docs/products/native-token-transfers/get-started/): Transfers staked assets natively between networks. + - [**Messaging**](/docs/products/messaging/overview/): Moves staking rewards and governance signals across chains. + +## Next Steps + +Follow these steps to get started with NTT: + +[timeline(wormhole-docs/.snippets/text/products/native-token-transfers/overview/ntt-timeline.json)] \ No newline at end of file diff --git a/products/native-token-transfers/reference/.pages b/products/native-token-transfers/reference/.pages new file mode 100644 index 000000000..5793ccfb9 --- /dev/null +++ b/products/native-token-transfers/reference/.pages @@ -0,0 +1,3 @@ +title: Reference +nav: +- 'NTT CLI Commands': 'cli-commands.md' \ No newline at end of file diff --git a/products/native-token-transfers/reference/cli-commands.md b/products/native-token-transfers/reference/cli-commands.md new file mode 100644 index 000000000..4f2c705b6 --- /dev/null +++ b/products/native-token-transfers/reference/cli-commands.md @@ -0,0 +1,72 @@ +--- +title: NTT CLI Commands +description: A comprehensive guide to the Native Token Transfers (NTT) CLI, detailing commands for managing token transfers across chains within the Wormhole ecosystem. +categories: NTT, Transfer +--- + +# NTT CLI Commands + +## Introduction + +The NTT Command-Line Interface (CLI) is a powerful tool for managing native token transfers across multiple blockchain networks within the Wormhole ecosystem. This page provides a comprehensive list of available commands, their descriptions, and examples to help you interact with and configure the NTT system effectively. Whether initializing deployments, updating configurations, or working with specific chains, the NTT CLI simplifies these operations through its intuitive commands. + +If you haven't installed the NTT CLI yet, follow the [NTT Installation](/docs/products/native-token-transfers/get-started/#install-ntt-cli){target=\_blank} instructions to set it up before proceeding. + +## Table of Commands + +The following table lists the available NTT CLI commands, descriptions, and examples. + +To explore detailed information about any NTT CLI command, including its options and examples, you can append `--help` to the command. This will display a comprehensive guide for the specific command. + +### General Commands + +| Command | Description | Example | +|-----------------------------------------|--------------------------------------------------------|--------------------------------------------------------------------| +| `ntt update` | update the NTT CLI | `ntt update` | +| `ntt new ` | create a new NTT project | `ntt new my-ntt-project` | +| `ntt add-chain ` | add a chain to the deployment file | `ntt add-chain Ethereum --token 0x1234... --mode burning --latest` | +| `ntt upgrade ` | upgrade the contract on a specific chain | `ntt upgrade Solana --ver 1.1.0` | +| `ntt clone
` | initialize a deployment file from an existing contract | `ntt clone Mainnet Solana Sol5678...` | +| `ntt init ` | initialize a deployment file | `ntt init devnet` | +| `ntt pull` | pull the remote configuration | `ntt pull` | +| `ntt push` | push the local configuration | `ntt push` | +| `ntt status` | check the status of the deployment | `ntt status` | + +### Configuration Commands + +| Command | Description | Example | +|----------------------------------------------|-----------------------------------------|------------------------------------------------| +| `ntt config set-chain ` | set a configuration value for a chain | `ntt config set-chain Ethereum scan_api_key` | +| `ntt config unset-chain ` | unset a configuration value for a chain | `ntt config unset-chain Ethereum scan_api_key` | +| `ntt config get-chain ` | get a configuration value for a chain | `ntt config get-chain Ethereum scan_api_key` | + +### Solana Commands + +| Command | Description | Example | +|------------------------------------------------|----------------------------------------------------------|-------------------------------------------------| +| `ntt solana key-base58 ` | print private key in base58 | `ntt solana key-base58 /path/to/keypair.json` | +| `ntt solana token-authority ` | print the token authority address for a given program ID | `ntt solana token-authority Sol1234...` | +| `ntt solana ata ` | print the token authority address for a given program ID | `ntt solana ata Mint123... Owner123... token22` | + +## Where to Go Next + +
+ + +- :octicons-gear-16:{ .lg .middle } **Configure NTT** + + --- + + Find information on configuring NTT, including guidance on setting Owner and Pauser access control roles and management of rate-limiting. + + [:custom-arrow: Configure your NTT deployment](/docs/products/native-token-transfers/configuration/access-control/) + +- :octicons-question-16:{ .lg .middle } **NTT FAQs** + + --- + + Frequently asked questions about Wormhole Native Token Transfers, including cross-chain lending, SDK usage, custom RPCs, and integration challenges. + + [:custom-arrow: Check out the FAQs](/docs/products/native-token-transfers/faqs/) + +
diff --git a/build/transfers/native-token-transfers/managers-transceivers.md b/products/native-token-transfers/reference/managers-transceivers.md similarity index 100% rename from build/transfers/native-token-transfers/managers-transceivers.md rename to products/native-token-transfers/reference/managers-transceivers.md diff --git a/build/start-building/products.md b/products/products.md similarity index 62% rename from build/start-building/products.md rename to products/products.md index f5ed6a673..0c524ceda 100644 --- a/build/start-building/products.md +++ b/products/products.md @@ -16,9 +16,9 @@ Beyond transfers, Wormhole extends interoperability with tools for cross-chain d Wormhole offers different solutions for cross-chain asset transfer, each designed for various use cases and integration requirements. -- [**Native Token Transfers (NTT)**](/docs/learn/transfers/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks -- [**Token Bridge**](/docs/learn/transfers/token-bridge/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages -- [**Settlement**](/docs/learn/messaging/wormhole-settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods +- [**Native Token Transfers (NTT)**](/docs/products/native-token-transfers/overview/){target=\_blank} - a mechanism to transfer native tokens cross-chain seamlessly without conversion to a wrapped asset. Best for projects that require maintaining token fungibility and native chain functionality across multiple networks +- [**Token Bridge**](/docs/products/token-bridge/overview/){target=\_blank} - a bridging solution that uses a lock and mint mechanism. Best for projects that need cross-chain liquidity using wrapped assets and the ability to send messages +- [**Settlement**](/docs/products/settlement/overview/){target=\_blank} - intent-based protocols enabling fast multichain transfers, optimized liquidity flows, and interoperability without relying on traditional bridging methods
@@ -45,16 +45,20 @@ Wormhole offers different solutions for cross-chain asset transfer, each designe
+In the following video, Wormhole Foundation DevRel Pauline Barnades walks you through the key differences between Wormhole’s Native Token Transfers (NTT) and Token Bridge and how to select the best option for your use case: + +
+ Beyond asset transfers, Wormhole provides additional tools for cross-chain data and governance. ## Bridging UI -[**Connect**](/docs/build/transfers/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. +[**Connect**](/docs/products/connect/overview/){target=\_blank} is a pre-built bridging UI for cross-chain token transfers, requiring minimal setup. Best for projects seeking an easy-to-integrate UI for bridging without modifying contracts. ## Real-time Data -[**Queries**](/docs/build/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. +[**Queries**](/docs/products/queries/overview/){target=\_blank} is a data retrieval service to fetch on-chain data from multiple networks. Best for applications that need multichain analytics, reporting, and data aggregation. ## Multichain Governance -[**MultiGov**](/docs/learn/governance/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. \ No newline at end of file +[**MultiGov**](/docs/products/multigov/overview/){target=\_blank} is a unified governance framework that manages multichain protocol governance through a single mechanism. Best for projects managing multichain governance and protocol updates. \ No newline at end of file diff --git a/products/queries/.pages b/products/queries/.pages new file mode 100644 index 000000000..c03aa7cbf --- /dev/null +++ b/products/queries/.pages @@ -0,0 +1,7 @@ +title: Queries +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- 'FAQs': faqs.md +- reference diff --git a/build/queries/faqs.md b/products/queries/faqs.md similarity index 91% rename from build/queries/faqs.md rename to products/queries/faqs.md index c3fe4f198..5f755f1b2 100644 --- a/build/queries/faqs.md +++ b/products/queries/faqs.md @@ -21,7 +21,7 @@ categories: Queries ## Are there any query examples? -Certainly. You can find a complete guide on the [Use Queries page](/docs/build/queries/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: +Certainly. You can find a complete guide on the [Use Queries page](/docs/products/queries/guides/use-queries/){target=\_blank}. Additionally, you can find full code examples in the following repositories: - [Basic Example Query Demo](https://github.com/wormholelabs-xyz/example-queries-demo/){target=\_blank} - [Solana Stake Pool Example Query](https://github.com/wormholelabs-xyz/example-queries-solana-stake-pool){target=\_blank} @@ -34,7 +34,7 @@ The Guardian node calculates an ECDSA signature using [`Sign` function of the cr ```keccak256("query_response_0000000000000000000|"+keccak256(responseBytes))``` -See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_key.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. +See the [Guardian Key Usage](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_signer.md){target=\_blank} white paper for more background. Once this signature is created, the Guardian's index in the Guardian set is appended to the end. !!! note If you are used to `ecrecover` you will notice that the `v` byte is `0` or `1` as opposed to `27` or `28`. The `signaturesToEvmStruct` method in the [Query TypeScript SDK](https://npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} accounts for this as well as structuring the signatures into an `IWormhole.SignatureStruct[]`. diff --git a/products/queries/get-started.md b/products/queries/get-started.md new file mode 100644 index 000000000..2b3978811 --- /dev/null +++ b/products/queries/get-started.md @@ -0,0 +1,80 @@ +--- +title: Get Started with Queries +description: Follow this guide to run your first multichain, verifiable query with the Wormhole Queries SDK and Proxy, using eth_call to fetch token metadata. +categories: Queries +--- + +# Get Started with Queries + +## Introduction + +[Queries](/docs/products/queries/overview) lets you fetch on-chain data from supported blockchains using `eth_call`-style requests without submitting transactions or paying gas. The Guardian network signs the result, making it verifiable and suitable for use on-chain. + +This guide walks you through requesting an API key, constructing your first query using the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, and decoding the result. + +## Prerequisites + +Before you begin, make sure you have the following: + + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - A basic understanding of JavaScript or TypeScript + - An RPC endpoint for a supported chain (e.g., Ethereum Sepolia) + - A Wormhole Queries API key + +## Request an API Key + +Wormhole Queries is in closed beta, but you can start building today. + +To interact with the system, you will use the Query Proxy. This hosted service receives your query, routes it to the appropriate chain, and returns a signed, verifiable response from the Guardian network. The Query Proxy allows you to fetch on-chain data without infrastructure overhead. + +To request access, join the beta by filling out the [access form](https://forms.clickup.com/45049775/f/1aytxf-10244/JKYWRUQ70AUI99F32Q){target=\_blank}. Once approved, you will receive an API key via email. + +## Construct a Query and Decode the Response + +Using the Wormhole Query Proxy, you will write a lightweight script to query a token contract's `name()` on Ethereum Sepolia. The response is signed by the Guardian network and locally decoded for use in your application. + +1. Create a new directory for your script and initialize a Node.js project: + + ```bash + mkdir queries + cd queries + npm init -y + ``` + +2. Add the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank}, [Axios](https://www.npmjs.com/package/axios){target=\_blank}, [Web3](https://www.npmjs.com/package/web3){target=\_blank}, and helper tools: + + ```bash + npm install axios web3 @wormhole-foundation/wormhole-query-sdk + npm install -D tsx typescript + ``` + +3. Add a new `query.ts` script where you will write and run your query logic: + + ```bash + touch query.ts + ``` + +4. Paste the following script into `query.ts` to build and submit a query to the token contract's `name()` function on Ethereum Sepolia, then decode the Guardian-signed response: + + ```typescript + --8<-- "code/products/queries/get-started/snippet-1.ts" + ``` + +5. Use your API key to execute the script: + + ```bash + API_KEY=INSERT_QUERIES_API_KEY npx tsx query.ts + ``` + +The expected output should be similar to this: + +--8<-- "code/products/queries/get-started/snippet-2.html" + +## Next Steps + +Now that you've successfully run your first verifiable query, you are ready to go deeper. Check out the following guides to build on what you've learned: + +- [**Query Solana**](https://github.com/wormhole-foundation/demo-queries-ts/blob/main/src/query_solana_stake_pool.ts){target=\_blank}: Try fetching Solana stake pools to see how cross-chain queries apply beyond EVM. +- [**Use Queries**](/docs/products/queries/guides/use-queries){target=\_blank}: Take a deeper look at the complete Queries lifecycle. +- **Browse the [Supported Networks](/docs/products/queries/reference/supported-networks){target=\_blank}**: See where Queries are supported. + diff --git a/products/queries/guides/.pages b/products/queries/guides/.pages new file mode 100644 index 000000000..f21f9f42c --- /dev/null +++ b/products/queries/guides/.pages @@ -0,0 +1,3 @@ +title: Guides +nav: +- 'Use Queries': use-queries.md diff --git a/build/queries/use-queries.md b/products/queries/guides/use-queries.md similarity index 67% rename from build/queries/use-queries.md rename to products/queries/guides/use-queries.md index 788463103..b67bc76cd 100644 --- a/build/queries/use-queries.md +++ b/products/queries/guides/use-queries.md @@ -10,28 +10,6 @@ You can visit the [Example Queries Demo](https://wormholelabs-xyz.github.io/exam This guide covers using a simple `eth_call` request to get the total supply of WETH on Ethereum. -## RPC Basics - -Before digging into anything Queries-specific, this page will look at how to make an [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} against a public Ethereum RPC. Suppose you'd like to query the WETH contract for its total supply; before making a request, you need some information about the contract you want to call, including: - -- **To** - the contract to call. WETH is [0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2){target=\_blank} -- **Data** - the method identifier and ABI-encoded parameters, which can be obtained as follows: `web3.eth.abi.encodeFunctionSignature("totalSupply()")` which yields `0x18160ddd` -- **Block ID** - the block number, hash, or tag. Tag options include `latest,` `safe,` or `finalized` - -The prepared curl request is as follows: - -```bash title="eth_call JSON-RPC request" ---8<-- 'code/build/queries/use-queries/eth-call-initial-request.txt' -``` - -And the corresponding response is: - -```bash title="eth_call JSON-RPC reponse" ---8<-- 'code/build/queries/use-queries/eth-call-initial-response.txt' -``` - -Converting the returned value of the executed call from hexidecimal results in the value `3172615244782286193073777`. You can compare your result to the [**Read Contract**](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#readContract){target=\_blank} tab in Etherscan. Your result will be different as WETH is minted/burned over time. - ## Construct a Query {: #construct-a-query} You can use the [Wormhole Query SDK](https://www.npmjs.com/package/@wormhole-foundation/wormhole-query-sdk){target=\_blank} to construct a query. You will also need an RPC endpoint from the provider of your choice. This example uses [Axios](https://www.npmjs.com/package/axios){target=\_blank} for RPC requests. Ensure that you also have [TypeScript](https://www.typescriptlang.org/download/){target=\_blank} installed. @@ -45,44 +23,44 @@ In order to make an `EthCallQueryRequest`, you need a specific block number or h You can request the latest block from a public node using `eth_getBlockByNumber`. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:12:12' ---8<-- 'code/build/queries/use-queries/test-full.jsx:19:26' +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:12:12' +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:19:26' ``` Then construct the call data. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:13:16' +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:13:16' ``` Finally, put it all together in a `QueryRequest`. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:44:53' +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:44:53' ``` This request consists of one `PerChainQueryRequest`, which is an `EthCallQueryRequest` to Ethereum. You can use `console.log` to print the JSON object and review the structure. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:54:54' -// { -// "nonce": 0, -// "requests": [ -// { -// "chainId": 2, -// "query": { -// "callData": [ -// { -// "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", -// "data": "0x18160ddd" -// } -// ], -// "blockTag": "0x11e9068" -// } -// } -// ], -// "version": 1 -// } +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:54:54' + // { + // "nonce": 0, + // "requests": [ + // { + // "chainId": 2, + // "query": { + // "callData": [ + // { + // "to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + // "data": "0x18160ddd" + // } + // ], + // "blockTag": "0x11e9068" + // } + // } + // ], + // "version": 1 + // } ``` ## Mock a Query @@ -90,24 +68,26 @@ This request consists of one `PerChainQueryRequest`, which is an `EthCallQueryRe For easier testing, the Query SDK provides a `QueryProxyMock` method. This method will perform the request and sign the result with the [Devnet](https://github.com/wormhole-foundation/wormhole/blob/main/DEVELOP.md){target=\_blank} Guardian key. The `mock` call returns the same format as the Query Proxy. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:55:57' -// { -// signatures: ['...'], -// bytes: '...' -// } +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:55:57' + // { + // signatures: ['...'], + // bytes: '...' + // } ``` This response is suited for on-chain use, but the SDK also includes a parser to make the results readable via the client. ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx:58:64' -// Mock Query Result: 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee (3172556167631284394053614) +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx:58:64' + // Mock Query Result: + // 0x000000000000000000000000000000000000000000029fd09d4d81addb3ccfee + // (3172556167631284394053614) ``` Testing this all together might look like the following: ```jsx ---8<-- 'code/build/queries/use-queries/test-full.jsx' +--8<-- 'code/products/queries/guides/use-queries/test-full.jsx' ``` ### Fork Testing @@ -120,7 +100,7 @@ anvil --fork-url https://ethereum.publicnode.com In order for mock requests to verify against the Mainnet Core Contract, you need to replace the current Guardian set with the single Devnet key used by the mock. -Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/build/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. +Here's an example for Ethereum Mainnet, where the `-a` parameter is the [Core Contract address](/docs/products/reference/contract-addresses/#core-contracts){target=\_blank} on that chain. ```jsx npx @wormhole-foundation/wormhole-cli evm hijack -a 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B -g 0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe @@ -133,7 +113,7 @@ If you are using `EthCallWithFinality`, you will need to mine additional blocks The standardized means of making a `QueryRequest` with an API key is as follows: ```jsx ---8<-- 'code/build/queries/use-queries/query-request-with-api-key.jsx' +--8<-- 'code/products/queries/guides/use-queries/query-request-with-api-key.jsx' ``` Remember to always take steps to protect your sensitive API keys, such as defining them in `.env` files and including such files in your `.gitignore`. @@ -166,7 +146,7 @@ See the [QueryDemo](https://github.com/wormholelabs-xyz/example-queries-demo/blo ??? code "View the complete `QueryDemo`" ```solidity - --8<-- 'code/build/queries/use-queries/query-demo.sol' + --8<-- 'code/products/queries/guides/use-queries/query-demo.sol' ``` ## Submit a Query Response On-Chain @@ -176,5 +156,5 @@ The `QueryProxyQueryResponse` result requires a slight tweak when submitting to This example submits the transaction to the demo contract: ```jsx ---8<-- 'code/build/queries/use-queries/query-proxy-query-response.jsx' -``` +--8<-- 'code/products/queries/guides/use-queries/query-proxy-query-response.jsx' +``` \ No newline at end of file diff --git a/products/queries/overview.md b/products/queries/overview.md new file mode 100644 index 000000000..815129ff4 --- /dev/null +++ b/products/queries/overview.md @@ -0,0 +1,68 @@ +--- +title: Queries Overview +description: Learn how Wormhole Queries enable smart contracts to fetch real-time, Guardian-verified data across multiple blockchains. +categories: Queries +--- + +# Queries Overview + +Queries provide on-demand access to Guardian-attested on-chain data. They allow smart contracts to fetch real-time, verifiable data from across the multichain ecosystem, such as prices, rates, and liquidity. + +## Key Features + +- **On-demand data access**: Fetch price feeds, interest rates, and other data in real-time. +- **Guardian attested**: All data is signed by [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} for trustless validation. +- **Cross-chain ready**: Request data on one chain, use it on another. +- **Smart contract integration**: Results are delivered as [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank}, readable by smart contracts. +- **Chain agnostic**: works across supported EVM chains, Solana, Sui, and [more](/docs/products/queries/reference/supported-networks/){target=\_blank}. + +## How It Works + +A query request follows a simple but robust lifecycle. The off-chain service responsible for handling requests is called the CCQ Server (Cross-Chain Query Server), also referred to as the Query Server throughout this documentation. + +1. An off-chain app sends a query to the CCQ Server via HTTPS +2. The CCQ Server checks the request and shares it with [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} +3. [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} independently fetch the data, verify it, and sign the result +4. Once enough Guardians (2/3 quorum) return matching results, the CCQ Server aggregates and sends the final response +5. The off-chain app submits this result to a smart contract, which verifies the Guardian signatures and uses the data + +The CCQ Server is permissioned but trustless. Most queries resolve in under one second, and Guardians retry failed requests for up to one minute. Up to 255 queries can be batched together to optimize performance, supporting efficient multichain workflows. + +![The architecture flow of a query](/docs/images/products/queries/overview/overview-1.webp) + +## Use Cases + +Queries enable a wide range of cross-chain applications. Below are common use cases and the Wormhole stack components you can use to build them. + +- **Borrowing and Lending Across Chains (e.g., [Folks Finance](https://wormhole.com/case-studies/folks-finance){target=\_blank})** + + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch rates and prices in real-time. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Sync actions between chains. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Transfer collateral as native assets. + +- **Cross-Chain Swaps and Liquidity Aggregation (e.g., [StellaSwap](https://app.stellaswap.com/exchange/swap){target=\_blank})** + + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch live prices optimal trade execution. + - [**Connect**](/docs/products/connect/overview/){target=\_blank}: Handle user-friendly asset transfers. + - [**Native Token Transfer**](/docs/products/native-token-transfers/overview/){target=\_blank}: Moves native tokens. + +- **Real-Time Price Feeds and Trading Strategies (e.g., [Infinex](https://wormhole.com/case-studies/infinex){target=\_blank})** + + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch price feeds. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Trigger trades. + +- **Multichain Prediction Markets** + + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Fetch market data and odds. + - [**Settlement**](/docs/products/settlement/overview/){target=\_blank}: Automates token execution. + +- **Oracle Networks (e.g., [Pyth](https://wormhole.com/case-studies/pyth){target=\_blank})** + + - [**Queries**](/docs/products/queries/get-started/){target=\_blank}: Source data from chains. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Ensures tamper-proof data relay across networks. + +## Next Steps + +Follow these steps to get started with Queries: + +[timeline(wormhole-docs/.snippets/text/products/queries/queries-timeline.json)] diff --git a/products/queries/reference/.pages b/products/queries/reference/.pages new file mode 100644 index 000000000..7c1f6fff1 --- /dev/null +++ b/products/queries/reference/.pages @@ -0,0 +1,4 @@ +title: Reference +nav: +- 'Supported Networks': supported-networks.md +- 'Supported Methods': supported-methods.md \ No newline at end of file diff --git a/products/queries/reference/supported-methods.md b/products/queries/reference/supported-methods.md new file mode 100644 index 000000000..83ee1720c --- /dev/null +++ b/products/queries/reference/supported-methods.md @@ -0,0 +1,55 @@ +--- +title: Queries Supported Methods +description: Retrieve multichain data via historical timestamp queries, finality confirmation queries, and Solana lookups. +categories: Queries +--- + +# Supported Methods + +Wormhole Queries provides on-demand access to [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}-attested on-chain data through a simple REST endpoint. It offers a faster, gasless alternative to traditional transaction-based data retrieval, removing the need for gas fees and transaction finality delays. Requests are handled off-chain and processed by the Guardians, delivering verified data efficiently and cost-effectively. + +This page describes Wormhole Queries, their functionality, and available methods, aiming to assist new developers in utilizing the service. + +## Supported Query Types + +Wormhole currently supports five distinct query types, each designed for specific data retrieval tasks across various chains. + +!!! note + For a more comprehensive technical description and further specifics on each query type, please consult the [white paper](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md). + + +### eth_call + +The [`eth_call`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank} query type allows you to perform read-only calls to a smart contract on a specific block, identified by its number or hash. Some of eth_call's configurations include: + +- **Batching** - group multiple calls, even to different contracts, into a single query targeting the same block, which is processed as one batch RPC call to simplify on-chain verification +- **Capacity** - batch up to 255 individual in a single eth_call query +- **Result data** - provides the specified block's number, hash, timestamp, and the output from the contract call + +### eth_call_by_timestamp + +The [`eth_call_by_timestamp`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#timestamp-and-block-id-hints-in-eth_call_by_timestamp){target=\_blank} query is similar to a standard `eth_call` but targets a specific timestamp instead of a block ID. This is useful for retrieving on-chain data based on a precise point in time, especially for correlating information across different chains. + +The query returns your target timestamp and the latest block details at or before your specified `target_time` immediately preceding the subsequent block. + +### eth_call_with_finality + +The [`eth_call_with_finality`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#desired-finality-in-eth_call_with_finality){target=\_blank} query type functions like a standard `eth_call`, but with an added critical assurance: it will only return the query results once the specified block has reached a designated level of finality on its chain. + +You can specify one of two finality levels for your query: + +- **Finalized** - indicates the highest level of assurance that a block is permanent and will not be altered or removed from the chain +- **Safe** - refers to a block considered highly unlikely to be reorganized, offering a substantial degree of confidence, though the network's consensus may not fully finalize it + +!!! note + If the target blockchain does not natively support or recognize the safe finality tag, requesting safe finality will be treated as a request for finalized finality instead. + +### sol_account + +The [`sol_account`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana-queries){target=\_blank} query reads on-chain data for one or more specified accounts on the Solana blockchain. This functionality is similar to using Solana's native [`getMultipleAccounts`](https://solana.com/docs/rpc/http/getmultipleaccounts){target=\_blank} RPC method, enabling you to retrieve information for multiple accounts simultaneously + +### sol_pda + +The [`sol_pda`](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0013_ccq.md#solana_queries){target=\_blank} query reads data for one or more Solana [Program Derived Addresses](https://www.anchor-lang.com/docs/pdas){target=\_blank}. It streamlines the standard process of deriving a PDA and fetching its account data. + +This is particularly useful for accessing multiple PDAs owned by a specific program or for verifying Solana PDA derivations on another blockchain, such as how associated token accounts are all derived from the [Associated Token Account Program](https://spl.solana.com/associated-token-account){target=\_blank}. \ No newline at end of file diff --git a/products/queries/reference/supported-networks.md b/products/queries/reference/supported-networks.md new file mode 100644 index 000000000..7954b4f83 --- /dev/null +++ b/products/queries/reference/supported-networks.md @@ -0,0 +1,36 @@ +--- +title: Queries Supported Networks +description: Reference table of chains supported by Wormhole Queries, including method support, finality, and expected historical data availability. +categories: Queries +--- + +# Supported Networks + +This page provides a quick reference for chains supported by Wormhole Queries, including each chain's Wormhole chain ID and the level of support for key methods: [`eth_call`](/docs/products/queries/reference/supported-methods/#eth_call){target=\_blank}, [`eth_call_by_timestamp`](/docs/products/queries/reference/supported-methods/#eth_call_by_timestamp){target=\_blank}, and [`eth_call_with_finality`](/docs/products/queries/reference/supported-methods/#eth_call_with_finality){target=\_blank}. + +The **Expected History** column shows how much recent state data is typically available for querying, though this can vary depending on the chain and the configuration of each Guardian node. + +The support shown in the table reflects what has been confirmed through testing. However, query success ultimately depends on whether the underlying call can be executed on each Guardian’s RPC node. + +For example, many chains use a fork of [Geth](https://github.com/ethereum/go-ethereum){target=\_blank}, which by default retains 128 blocks of state in memory (unless archive mode is enabled). On Ethereum mainnet, this covers around 25 minutes of history—but on faster chains like Optimism, it may span only about three minutes. While Guardian nodes are expected to have access to recent state, there are currently no guarantees on how far back historical data is available. + +## Mainnet + +| Chain | Wormhole Chain ID | eth_call | eth_call_by_timestamp | eth_call_with_finality | Expected History | +|:-------------:|:-----------------:|:--------:|:---------------------:|:----------------------:|:----------------:| +| Ethereum | 2 | ✅ | ✅ | ✅ | 128 blocks | +| BSC | 4 | ✅ | ✅ | ✅ | 128 blocks | +| Polygon | 5 | ✅ | ✅ | ✅ | 128 blocks | +| Avalanche | 6 | ✅ | ✅ | ✅ | 32 blocks | +| Oasis Emerald | 7 | ✅ | ✅ | ✅ | archive | +| Fantom | 10 | ✅ | ✅ | ✅ | 16 blocks | +| Karura | 11 | ✅ | ✅ | ✅ | archive | +| Acala | 12 | ✅ | ✅ | ✅ | archive | +| Kaia | 13 | ✅ | ✅ | ✅ | 128 blocks | +| Celo | 14 | ✅ | ℹ️ | ✅ | 128 blocks | +| Moonbeam | 16 | ✅ | ℹ️ | ✅ | 256 blocks | +| Arbitrum One | 23 | ✅ | ✅ | ✅ | ~6742 blocks | +| Optimism | 24 | ✅ | ✅ | ❌ | 128 blocks | +| Base | 30 | ✅ | ✅ | ✅ | archive | + +ℹ️`EthCallByTimestamp` arguments for `targetBlock` and `followingBlock` are currently required for requests to be successful on these chains. \ No newline at end of file diff --git a/products/reference/.pages b/products/reference/.pages new file mode 100644 index 000000000..26b760b36 --- /dev/null +++ b/products/reference/.pages @@ -0,0 +1,9 @@ +title: Reference +nav: +- 'Chain IDs': chain-ids.md +- 'Contract Addresses': contract-addresses.md +- 'Wormhole Finality': consistency-levels.md +- 'Wormhole-Formatted Addresses': wormhole-formatted-addresses.md +- 'Supported Networks': supported-networks.md +- 'Testnet Faucets': testnet-faucets.md +- 'Glossary': glossary.md diff --git a/build/reference/chain-ids.md b/products/reference/chain-ids.md similarity index 91% rename from build/reference/chain-ids.md rename to products/reference/chain-ids.md index d143f4404..7299bafc4 100644 --- a/build/reference/chain-ids.md +++ b/products/reference/chain-ids.md @@ -11,4 +11,4 @@ The following table documents the chain IDs used by Wormhole and places them alo !!! note Please note, Wormhole chain IDs are different than the more commonly referenced EVM [chain IDs](https://eips.ethereum.org/EIPS/eip-155){target=\_blank}, specified in the Mainnet and Testnet ID columns. ---8<-- 'text/build/reference/chain-ids/chain-ids.md' +--8<-- 'text/products/reference/chain-ids/chain-ids.md' diff --git a/build/reference/consistency-levels.md b/products/reference/consistency-levels.md similarity index 91% rename from build/reference/consistency-levels.md rename to products/reference/consistency-levels.md index 7ffa65ce8..ea6bc3c67 100644 --- a/build/reference/consistency-levels.md +++ b/products/reference/consistency-levels.md @@ -8,4 +8,4 @@ categories: Reference The following table documents each chain's `consistencyLevel` values (i.e., finality reached before signing). The consistency level defines how long the Guardians should wait before signing a VAA. The finalization time depends on the specific chain's consensus mechanism. The consistency level is a `u8`, so any single byte may be used. However, a small subset has particular meanings. If the `consistencyLevel` isn't one of those specific values, the `Otherwise` column describes how it's interpreted. ---8<-- 'text/build/reference/consistency-levels/consistency-levels.md' +--8<-- 'text/products/reference/consistency-levels/consistency-levels.md' diff --git a/products/reference/contract-addresses.md b/products/reference/contract-addresses.md new file mode 100644 index 000000000..cdf37eed7 --- /dev/null +++ b/products/reference/contract-addresses.md @@ -0,0 +1,42 @@ +--- +title: Contract Addresses +description: This page documents the deployed contract addresses of the Wormhole contracts on each chain, including Core Contracts, TokenBridge, and more. +categories: Reference +--- + +# Contract Addresses + +## Core Contracts + +--8<-- 'text/products/reference/contract-addresses/core-contracts.md' + +## Token Bridge + +--8<-- 'text/products/reference/contract-addresses/token-bridge.md' + +## Wormhole Relayer + +--8<-- 'text/products/reference/contract-addresses/relayer.md' + +## CCTP + +--8<-- 'text/products/reference/contract-addresses/cctp.md' + +## Settlement Token Router + +=== "Mainnet" + +
Chain NameContract Address
Ethereum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Solana28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe
Arbitrum0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Avalanche0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Base0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Optimism0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
Polygon0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47
+ +=== "Testnet" + +
Chain NameContract Address
SolanatD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md
Arbitrum Sepolia0xe0418C44F06B0b0D7D1706E01706316DBB0B210E
Optimism Sepolia0x6BAa7397c18abe6221b4f6C3Ac91C88a9faE00D8
+ + +## Read-Only Deployments + +--8<-- 'text/products/reference/contract-addresses/read-only.md' + +!!!note + Read-only deployments allow Wormhole messages to be received on chains not fully integrated with Wormhole Guardians. These deployments support cross-chain data verification but cannot originate messages. For example, a governance message can be sent from a fully integrated chain and processed on a read-only chain, but the read-only chain cannot send messages back. + diff --git a/learn/glossary.md b/products/reference/glossary.md similarity index 82% rename from learn/glossary.md rename to products/reference/glossary.md index 0f06b1012..b87ee819f 100644 --- a/learn/glossary.md +++ b/products/reference/glossary.md @@ -12,11 +12,11 @@ This glossary is an index of technical term definitions for words commonly used Wormhole assigns a unique `u16` integer chain ID to each supported blockchain. These chain IDs are specific to Wormhole and may differ from those used by blockchains to identify their networks. -You can find each chain ID documented on the [Wormhole Chain IDs](/docs/build/reference/chain-ids/){target=\_blank} page. +You can find each chain ID documented on the [Wormhole Chain IDs](/docs/products/reference/chain-ids/){target=\_blank} page. ## Consistency Level -The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page for details. +The level of finality (consistency) a transaction should meet before being signed by a Guardian. See the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page for details. ## Delivery Provider @@ -32,7 +32,7 @@ The finality of a transaction depends on its blockchain properties. Once a trans ## Guardian -A [Guardian](/docs/learn/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. +A [Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank} is one of the 19 parties running validators in the Guardian Network contributing to the VAA multisig. ## Guardian Network @@ -66,7 +66,7 @@ A Spy is a daemon that eavesdrops on the messages passed between Guardians, typi ## VAA -[Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. +[Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs) are the base data structure in the Wormhole ecosystem. They contain emitted messages along with information such as what contract emitted the message. ## Validator diff --git a/build/start-building/supported-networks.md b/products/reference/supported-networks.md similarity index 52% rename from build/start-building/supported-networks.md rename to products/reference/supported-networks.md index 2d8a582e3..21a297181 100644 --- a/build/start-building/supported-networks.md +++ b/products/reference/supported-networks.md @@ -8,11 +8,11 @@ categories: Reference Wormhole supports many blockchains across mainnet, testnet, and devnets. You can use these tables to verify if your desired chains are supported by the Wormhole products you plan to include in your integration. -## Networks +## Supported Networks by Product ---8<-- 'text/build/start-building/supported-networks/connect.md' ---8<-- 'text/build/start-building/supported-networks/ntt.md' ---8<-- 'text/build/start-building/supported-networks/token-bridge.md' ---8<-- 'text/build/start-building/supported-networks/cctp.md' ---8<-- 'text/build/start-building/supported-networks/settlement.md' ---8<-- 'text/build/start-building/supported-networks/multigov.md' \ No newline at end of file +--8<-- 'text/products/reference/supported-networks/connect.md' +--8<-- 'text/products/reference/supported-networks/ntt.md' +--8<-- 'text/products/reference/supported-networks/token-bridge.md' +--8<-- 'text/products/reference/supported-networks/cctp.md' +--8<-- 'text/products/reference/supported-networks/settlement.md' +--8<-- 'text/products/reference/supported-networks/multigov.md' \ No newline at end of file diff --git a/build/start-building/testnet-faucets.md b/products/reference/testnet-faucets.md similarity index 87% rename from build/start-building/testnet-faucets.md rename to products/reference/testnet-faucets.md index 9dd8dee01..b761f5817 100644 --- a/build/start-building/testnet-faucets.md +++ b/products/reference/testnet-faucets.md @@ -10,4 +10,4 @@ categories: Reference Don't let the need for testnet tokens get in the way of buildling your next great idea with Wormhole. Use this guide to quickly locate the testnet token faucets you need to deploy and test applications and contracts on Wormhole's supported networks. ---8<-- 'text/build/start-building/testnet-faucets/testnet-faucets.md' +--8<-- 'text/products/reference/testnet-faucets/testnet-faucets.md' diff --git a/build/reference/wormhole-formatted-addresses.md b/products/reference/wormhole-formatted-addresses.md similarity index 98% rename from build/reference/wormhole-formatted-addresses.md rename to products/reference/wormhole-formatted-addresses.md index dfc30b607..a7a79639a 100644 --- a/build/reference/wormhole-formatted-addresses.md +++ b/products/reference/wormhole-formatted-addresses.md @@ -92,13 +92,13 @@ Example conversions for EVM and Solana: === "EVM" ```typescript - --8<-- 'code/build/reference/formatted-addresses/evm.ts' + --8<-- 'code/products/reference/formatted-addresses/evm.ts' ``` === "Solana" ```typescript - --8<-- 'code/build/reference/formatted-addresses/solana.ts' + --8<-- 'code/products/reference/formatted-addresses/solana.ts' ``` The result is a standardized address format that is ready for cross-chain operations. diff --git a/products/settlement/.pages b/products/settlement/.pages new file mode 100644 index 000000000..b814f1820 --- /dev/null +++ b/products/settlement/.pages @@ -0,0 +1,6 @@ +title: Settlement +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- concepts +- 'FAQs': faqs.md diff --git a/products/settlement/concepts/.pages b/products/settlement/concepts/.pages new file mode 100644 index 000000000..9ef6dde62 --- /dev/null +++ b/products/settlement/concepts/.pages @@ -0,0 +1,3 @@ +title: Concepts +nav: +- 'Architecture': architecture.md \ No newline at end of file diff --git a/learn/transfers/settlement/architecture.md b/products/settlement/concepts/architecture.md similarity index 95% rename from learn/transfers/settlement/architecture.md rename to products/settlement/concepts/architecture.md index 1a6df7b00..33731130d 100644 --- a/learn/transfers/settlement/architecture.md +++ b/products/settlement/concepts/architecture.md @@ -20,7 +20,7 @@ Wormhole Liquidity Layer is a cross-chain transfer protocol that enables faster- Solvers concentrate their liquidity entirely on Solana, where they participate in permissionless on-chain English auctions (open ascending-price auctions where bidders publicly raise bids until only one bidder remains) to fulfill each cross-chain transfer. Upon the conclusion of each auction, the winning solver initiates a transfer from Solana to the specified destination chain. The solver rebalances inventory once the originating source chain transaction reaches finality and arrives to Solana. -![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/learn/transfers/settlement/architecture/architecture-1.webp) +![Wormhole Settlments Liquidity layer architecture diagram: source chain to hub to destination chain](/docs/images/products/settlement/concepts/architecture/architecture-1.webp) The Wormhole Liquidity Layer serves as the underlying chain abstraction infrastructure layer for protocols across Wormhole-connected ecosystems by enabling protocols to bundle call data containing arbitrary protocol actions, which can be executed atomically alongside each transfer. This feature allows developers to create fully chain-abstracted user experiences, including constructing natively cross-chain decentralized exchanges (DEXs), borrow-lend protocols, payment protocols, and other applications atop this layer. @@ -62,7 +62,7 @@ First, they lack a competitive price discovery mechanism as limit order prices a Mayan Swift addresses these limitations by implementing competitive on-chain English auctions on Solana as an embedded price discovery mechanism, fundamentally shifting solver competition from speed-based to price-based execution. Through this architecture, the solver offering the best possible price secures the right to fulfill the order within pre-specified deadline parameters. -![Mayan Swift - Intent-centric design](/docs/images/learn/transfers/settlement/architecture/architecture-2.webp) +![Mayan Swift - Intent-centric design](/docs/images/products/settlement/concepts/architecture/architecture-2.webp) ### Protocol Flow: How It Works @@ -81,7 +81,7 @@ Mayan Swift addresses these limitations by implementing competitive on-chain Eng Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross-Chain Transfer Protocol) mechanism and Wormhole messaging to enable secure, fee-managed asset transfers across chains. -![Mayan MCTP diagram](/docs/images/learn/transfers/settlement/architecture/architecture-3.webp) +![Mayan MCTP diagram](/docs/images/products/settlement/concepts/architecture/architecture-3.webp) ### Protocol Flow: How It Works @@ -92,12 +92,11 @@ Mayan MCTP is a cross-chain intents protocol that leverages Circle's CCTP (Cross The contract constructs a `BridgeWithFeeMsg` structure, which includes parameters such as the action type, payload type, nonce, destination address, gas drop, redeem fee, and an optional custom payload hash -2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/build/reference/consistency-levels/){target=\_blank} +2. **Intent submission** - the contract calls the CCTP messenger to deposit the tokens for bridging. A unique nonce is generated, and a corresponding fee-lock record is created in the contract's storage. This record includes the locked fee, gas drop parameters, and destination details. The constructed message is hashed and published through Wormhole. The protocol fee is deducted during this step, and the Wormhole message is broadcast with the specified [consistency (finality) level](/docs/products/reference/consistency-levels/){target=\_blank} 3. **Fulfillment** - on the destination chain, the protocol receives a CCTP message with corresponding signatures and verifies the payload using Wormhole's verification mechanism. Once validated, the redeemed tokens are transferred to the intended recipient, deducting the redeem fee as per protocol rules The protocol provides mechanisms for unlocking the fee once the bridging process is completed. This can occur immediately upon fulfillment or be batched for efficiency. In the fee unlock flow, the contract verifies the unlock message via Wormhole and then releases the locked fee to the designated unlocker address. ## Where to Go Next -- To learn more about available EVM functions, see the [Build on the Wormhole Liquidity Layer](/docs/build/transfers/settlement/liquidity-layer/){target=\_blank} guide - To learn how to integrate settlement routes into your application, see the [Integrate Wormhole Settlement Routes Using the SDK](https://github.com/wormhole-foundation/demo-mayanswift){target=\_blank} tutorial diff --git a/build/transfers/settlement/faqs.md b/products/settlement/faqs.md similarity index 100% rename from build/transfers/settlement/faqs.md rename to products/settlement/faqs.md diff --git a/products/settlement/get-started.md b/products/settlement/get-started.md new file mode 100644 index 000000000..e998c8df7 --- /dev/null +++ b/products/settlement/get-started.md @@ -0,0 +1,110 @@ +--- +title: Get Started +description: Perform a cross-chain token swap using Wormhole Settlement and the Mayan Swift route with the TypeScript SDK on mainnet. +categories: Settlement, Transfer +--- + +# Get Started + +[Settlement](/docs/products/settlement/overview/){target=\_blank} is Wormhole’s intent-based execution layer, enabling fast, multichain token transfers. It coordinates routing logic, relayers, and on-chain infrastructure to let users express what they want to be done, not how. + +This guide walks you through performing a real token swap using the [Mayan Swift route](https://mayan.finance){target=_blank}, one of the three integrated Settlement protocols, with the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=_blank}. + +By the end, you'll have a working script that: + +- Resolves token transfer routes using Mayan Swift +- Quotes and validates the best route +- Initiates a swap on a source chain and completes the transfer on a destination chain + +!!! note + Mayan Swift currently supports **mainnet only**. Attempting to run this demo on a testnet will fail. + +## Prerequisites + +Before you begin, ensure you have the following: + +- [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} installed on your machine +- Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#settlement){target=\_blank} + +This example uses Ethereum as the source chain and Solana as the destination. As a result, you'll need an Ethereum wallet with ETH for gas and a Solana wallet with SOL for fees. You can adapt the example to match your preferred chains. + +## Set Up a Project + +Start by scaffolding a basic Node.js project and installing the required SDKs. + +1. Create a new project folder: + + ```bash + mkdir settlement-swap + cd settlement-swap + npm init -y + ``` + +2. Install the required dependencies: + + ```bash + npm install @wormhole-foundation/sdk-connect \ + @wormhole-foundation/sdk-evm \ + @wormhole-foundation/sdk-solana \ + @mayanfinance/wormhole-sdk-route \ + dotenv + npm install -D typescript tsx + ``` + +3. Create the file structure: + + ```bash + mkdir src + touch src/helpers.ts src/swap.ts .env .gitignore + ``` + +4. Set up secure access to your wallets. This guide assumes you are loading your `MAINNET_ETH_PRIVATE_KEY` and `MAINNET_SOL_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [cast wallet](https://book.getfoundry.sh/reference/cast/cast-wallet/){target=_blank}. + + !!! warning + If you use a .env file during development, add it to your .gitignore to exclude it from version control. Never commit private keys or mnemonics to your repository. + +## Perform a Token Swap + +This section shows you how to perform a token swap using the Mayan Swift route. You will define a helper function to configure the source and destination chain signers. + +Then, you'll create a script that initiates a transfer on Ethereum, uses the Mayan Swift resolver to find valid routes, sends the transaction, and completes the transfer on Solana. + +1. Open `helper.ts` and define the `getSigner` utility function to load private keys, instantiate signers for Ethereum and Solana, and return the signers along with the Wormhole-formatted address: + + ```ts title="src/helpers.ts" + --8<-- "code/products/settlement/get-started/snippet-1.ts" + ``` + +2. In `swap.ts`, add the following script, which will handle all of the logic required to perform the token swap: + + ```ts title="src/swap.ts" + --8<-- "code/products/settlement/get-started/snippet-2.ts" + ``` + +3. Execute the script to initiate and complete the transfer: + + ```bash + npx tsx src/swap.ts + ``` + + If successful, you’ll see terminal output like this: + + --8<-- "code/products/settlement/get-started/snippet-3.html" + +Congratulations! You've just completed a cross-chain token swap from Ethereum to Solana using Settlement. + +## Customize the Integration + +You can tailor the example to your use case by adjusting: + +- **Tokens and chains**: Use `getSupportedTokens()` to explore what's available. +- **Source and destination chains**: Modify `sendChain` and `destChain` in `swap.ts`. +- **Transfer settings**: Update the amount or route parameters. +- **Signer management**: Modify `src/helpers.ts` to integrate with your preferred wallet setup. + +## Next Steps + +Once you've chosen a path, follow the corresponding guide to start building: + +- [**`demo-mayanswift`**](https://github.com/wormhole-foundation/demo-mayanswift){target=_blank}: Check out the repository for the full code example. + diff --git a/products/settlement/overview.md b/products/settlement/overview.md new file mode 100644 index 000000000..30895e233 --- /dev/null +++ b/products/settlement/overview.md @@ -0,0 +1,93 @@ +--- +title: Settlement Overview +description: Discover how Settlement enables fast, intent-based token transfers across chains using a unified system of solver auctions and integrated execution routes. +categories: Settlement, Transfer +--- + +# Settlement Overview + +Wormhole Settlement is a multichain transfer system that allows users to specify what they want to happen, such as sending or swapping tokens, without handling the execution themselves. Instead, off-chain agents called solvers compete to fulfill these user intents. + +Settlement prioritizes speed, execution quality, and reliability. Its primary route, Mayan Swift, leverages fast off-chain auctions among a curated set of solvers to achieve low-latency bridging with minimal slippage. All settlement steps remain verifiable on-chain through Wormhole messages. + +For broader use cases and protocol-level execution, Mayan MCTP provides an alternative path. It wraps Circle’s CCTP to facilitate native USDC bridging and token delivery in a single, verifiable flow. While slower due to chain finality constraints, MCTP offers a reliable mechanism for cross-chain transfers. + +## Key Features + +- **Intent-based architecture**: Users express what they want to happen (e.g., swap X for Y on chain Z), and solvers execute it. +- **Solver auctions**: Solvers compete in on-chain auctions for the right to fulfill intents, improving execution quality. +- **Fast and fallback-capable**: Combines high-speed execution with a reliable fallback path. +- **Minimal slippage**: Settlement abstracts away complex balancing operations and uses shuttle assets like USDC and tokens deployed via NTT. +- **On-chain verifiability**: Even though auctions are off-chain, all settlement steps remain verifiable on-chain via Wormhole messages. +- **Two integrated routes**: Mayan Swift for speed, Mayan MCTP for compatibility and redundancy. + +## How It Works + +At the core of Settlement are two components: + +- **Intents**: Signed transactions where a user defines what outcome they want (e.g., send USDC to another chain and receive ETH). It abstracts what the user wants, not how it should be executed. +- **Solvers**: Third-party agents that compete in auctions to fulfill these intents. They front capital, perform swaps or transfers, and receive fees in return. + +Settlement currently supports the following integrated protocols. + +### Mayan Swift + +Mayan Swift implements a traditional intent-based architecture, where solvers compete to fulfill user intents by utilizing their inventory. It offers fast execution, typically around 12 seconds. To participate, solvers must hold assets on multiple chains, which can lead to imbalances: some chains may get depleted while others accumulate excess. This requires occasional rebalancing and adds operational overhead. Despite that, Mayan Swift is ideal for high-speed transfers and benefits from open, competitive auctions that can drive down execution prices. + +The diagram below shows how Mayan Swift handles a cross-chain intent when a user wants to swap ARB on Arbitrum for WIF on Solana. Behind the scenes, the process is more involved and relies on solver-managed liquidity across both chains. + +1. **Solver initiates on Arbitrum**: Solver swaps ARB → ETH and deposits ETH into an escrow on Arbitrum. +2. **VAA emitted to Solana**: A [Verifiable Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank} triggers the solver to release SOL on Solana, which is swapped to WIF using an aggregator. +3. **User receives WIF**: Once the user receives WIF, a second VAA is emitted to finalize the transfer and releases the ETH held in the escrow to the solver. +4. **Failure handling**: If any step fails, the ETH in escrow is either retained or returned to the user — the solver only gets paid if execution succeeds. + +```mermaid +sequenceDiagram + participant User + participant Solver_ARB as Solver (Arbitrum) + participant Escrow + participant Wormhole + participant Solver_SOL as Solver (Solana) + participant Aggregator + + Note over User,Aggregator: User has ARB and wants WIF + + User->>Solver_ARB: Submit intent (ARB → WIF) + Solver_ARB->>Escrow: Swaps ARB → ETH and deposits ETH + Escrow-->>Wormhole: Emits VAA + Wormhole-->>Solver_SOL: Delivers VAA + Solver_SOL->>Aggregator: Releases SOL and swaps to WIF + Aggregator->>Solver_SOL: Receives WIF + Solver_SOL->>User: Sends WIF + User-->>Wormhole: Emits final VAA + Wormhole-->>Escrow: Confirms receipt + Escrow->>Solver_ARB: Releases ETH to solver +``` + +### Mayan MCTP + +Mayan MCTP is a fallback protocol that wraps Circle’s CCTP into the Settlement framework. It bundles USDC bridging and swaps into a single operation handled by protocol logic. This route is slower due to its reliance on chain finality. However, it provides broad compatibility and redundancy, making it useful when faster routes are unavailable or when targeting chains that aren’t supported by Swift. While typically more expensive due to protocol fees, it ensures reliable settlement when faster options are unavailable. + +## Use Cases + +- **Cross-Chain Perpetuals** + + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Provides fast token execution across chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Fetch live prices and manage position state across chains. + +- **Bridging Intent Library** + + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Handles user-defined bridge intents. + - [**Messaging**](/docs/products/messaging/overview/){target=\_blank}: Triggers cross-chain function calls. + +- **Multichain Prediction Markets** + + - [**Settlement**](/docs/products/settlement/get-started/){target=\_blank}: Executes token flows between chains. + - [**Queries**](/docs/products/queries/overview/){target=\_blank}: Gets market data and tracks state. + +## Next Steps + +Start building with Settlement or dive deeper into specific components: + +- **[Get Started with Settlement](/docs/products/settlement/get-started/)**: Follow a hands-on demo using Mayan Swift. +- **[Architecture Documentation](/docs/products/settlement/concepts/architecture/)**: Explore the Settlement architecture and components. \ No newline at end of file diff --git a/products/token-bridge/.pages b/products/token-bridge/.pages new file mode 100644 index 000000000..b23d0a9a8 --- /dev/null +++ b/products/token-bridge/.pages @@ -0,0 +1,9 @@ +title: Token Bridge +nav: +- 'Overview': overview.md +- 'Get Started': get-started.md +- guides +- tutorials +- concepts +- 'FAQs': faqs.md +- 'Portal Bridge': https://portalbridge.com/ diff --git a/products/token-bridge/concepts/.pages b/products/token-bridge/concepts/.pages new file mode 100644 index 000000000..255e2cdf0 --- /dev/null +++ b/products/token-bridge/concepts/.pages @@ -0,0 +1,4 @@ +title: Concepts +nav: +- 'Flow of a Transfer': transfer-flow.md +- 'Payload Structure': payload-structure.md diff --git a/products/token-bridge/concepts/payload-structure.md b/products/token-bridge/concepts/payload-structure.md new file mode 100644 index 000000000..85b83c4aa --- /dev/null +++ b/products/token-bridge/concepts/payload-structure.md @@ -0,0 +1,278 @@ +--- +title: Token Bridge Payload Structure +description: Discover the structure and purpose of each Token Bridge payload, including Transfer, TransferWithPayload, AssetMeta, and governance messages. +categories: Token-Bridge, Transfers +--- + +# Message and Payload Structure + +To enable secure and flexible cross-chain token transfers, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} defines a set of standardized payloads. These payloads are embedded in [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} and processed by bridge contracts on the source and destination chains. Each payload has a unique format and serves a specific role in the lifecycle of token bridging. + +This page outlines each payload type in detail. + +## Transfer + +The `Transfer` payload (ID = `1`) is the core mechanism for moving tokens across chains. It is emitted when a user locks or burns tokens on the source chain. On the destination chain, it instructs the bridge to either mint a wrapped token or release native tokens from custody. + +```text +PayloadID uint8 = 1 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +Fee uint256 +``` + +??? interface "Parameters" + + `PayloadID` ++"uint8"++ + + Value must be `1`, indicating a `Transfer` operation. + + --- + + `Amount` ++"uint256"++ + + Amount being transferred, truncated to 8 decimals for consistency across all chains. + + --- + + `TokenAddress` ++"bytes32"++ + + Address of the token. Left-zero-padded if shorter than 32 bytes + + --- + + `TokenChain` ++"uint16"++ + + Chain ID of the token. + + --- + + `To` ++"bytes32"++ + + Address of the recipient. Left-zero-padded if shorter than 32 bytes. + + --- + + `ToChain` ++"uint16"++ + + Chain ID of the recipient. + + --- + + `Fee` ++"uint256"++ + + Amount of tokens that the user is willing to pay as relayer fee. Must be less than Amount. Optional and can be claimed by relayers who submit the VAA on the target chain. + + +To keep `Transfer` messages small, they don't carry all the token's metadata. However, this means that before a token can be transferred to a new chain for the first time, the metadata needs to be bridged, and the wrapped asset needs to be created. Metadata, in this case, includes the number of decimals, which is a core requirement for instantiating a token. + +## AssetMeta + +Before a token can be transferred to a new chain for the first time, its metadata must be attested using the `AssetMeta` payload (ID = `2`). This ensures proper decimal precision and display. + +```text +PayloadID uint8 = 2 +TokenAddress [32]uint8 +TokenChain uint16 +Decimals uint8 +Symbol [32]uint8 +Name [32]uint8 +``` + +??? interface "Parameters" + + `PayloadID` ++"uint8"++ + + Value must be `2`, indicating a `AssetMeta` operation. + + --- + + `TokenAddress` ++"[32]uint8"++ + + Address of the token. Left-zero-padded if shorter than 32 bytes. + + --- + + `TokenChain` ++"uint16"++ + + Chain ID of the token. + + --- + + `Decimals` ++"uint8"++ + + Number of decimals the token uses on its native chain (not truncated to 8). + + --- + + `Symbol` ++"[32]uint8"++ + + Symbol of the token, UTF-8 encoded and padded to 32 bytes. + + --- + + `Name` ++"[32]uint8"++ + + Name of the token, UTF-8 encoded and padded to 32 bytes. + +## TransferWithPayload + +The `TransferWithPayload` payload (ID = `3`) extends the standard token transfer by allowing developers to include arbitrary data. This enables interactions with destination chain smart contracts, such as triggering swaps or staking. + +```text +PayloadID uint8 = 3 +Amount uint256 +TokenAddress bytes32 +TokenChain uint16 +To bytes32 +ToChain uint16 +FromAddress bytes32 +Payload bytes +``` + +??? interface "Parameters" + + `PayloadID` ++"uint8"++ + + Value must be `3`, indicating a `TransferWithPayload` operation. + + --- + + `Amount` ++"uint256"++ + + Amount being transferred, truncated to 8 decimals. + + --- + + `TokenAddress` ++"bytes32"++ + + Address of the token. Left-zero-padded if shorter than 32 bytes. + + --- + + `TokenChain` ++"uint16"++ + + Chain ID of the token. + + --- + + `To` ++"bytes32"++ + + Address of the recipient. Must be a contract capable of parsing and handling the payload. Left-zero-padded if shorter than 32 bytes + + --- + + `ToChain` ++"uint16"++ + + Chain ID of the recipient. + + --- + + `FromAddress` ++"bytes32"++ + + Address of the sender on the source chain. + + --- + + `Payload` ++"bytes"++ + + Arbitrary data passed to the recipient contract. Can be used for DeFi operations, authentication, or app-specific logic. + + +Unlike `Transfer`, the `TransferWithPayload` message must be redeemed by the recipient contract since only that contract can handle the custom payload properly. + +## RegisterChain + +The `RegisterChain` governance payload (Action ID = `1`) registers a Token Bridge emitter address for a foreign chain. This ensures the bridge only accepts messages from known peers. + +```text +Module [32]byte +Action uint8 = 1 +ChainId uint16 + +EmitterChainID uint16 +EmitterAddress [32]uint8 +``` + +??? interface "Parameters" + + `Module` ++"[32]byte"++ + + Module identifier. Left-padded with `TokenBridge` for Token Bridge. + + --- + + `Action` ++"uint8"++ + + Value must be `1`, indicating a `RegisterChain` operation. + + --- + + `ChainID` ++"uint16"++ + + The chain where this governance action should be applied. `0` is a valid value for all chains + + --- + + `EmitterChainID` ++"uint16"++ + + Chain ID of the registered emitter. + + --- + + `EmitterAddress` ++"[32]uint8"++ + + Address of the registered emitter, left-zero-padded if shorter than 32 bytes. + +This payload can only be emitted by the Wormhole governance contract, ensuring that each chain accepts messages only from one verified bridge emitter per remote chain. + +## UpgradeContract + +The `UpgradeContract` governance payload (Action ID = `2`) facilitates upgrades to the Token Bridge contract on a specific chain. + +```text +Module [32]byte +Action uint8 = 2 +ChainId uint16 + +NewContract [32]uint8 +``` + +??? interface "Parameters" + + `Module` ++"[32]byte"++ + + Module identifier, left-padded with `TokenBridge` for Token Bridge. + + --- + + `Action` ++"uint8"++ + + Value must be `2`, indicating an `UpgradeContract` operation. + + --- + + `ChainID` ++"uint16"++ + + The target chain where the governance action should be applied. + + --- + + `NewContract` ++"[32]uint8"++ + + Address of the new Token Bridge contract, left-zero-padded to 32 bytes. + +This message allows the Wormhole governance system to deploy new versions of the bridge while retaining control over interoperability and security. + +## Summary of Payload Structure + +| Payload Type | ID | Purpose | Who Emits It | +|-----------------------|---------------|------------------------------------------------------------------------|------------------------| +| `Transfer` | PayloadID `1` | Moves tokens between chains by minting or releasing on the destination | Token Bridge contract | +| `AssetMeta` | PayloadID `2` | Attests token metadata (decimals, symbol, name) before first transfer | Token Bridge contract | +| `TransferWithPayload` | PayloadID `3` | Transfers tokens along with a custom payload for contract execution | Token Bridge contract | +| `RegisterChain` | Action `1` | Registers a verified Token Bridge emitter for a foreign chain | Wormhole governance | +| `UpgradeContract` | Action `2` | Upgrades the Token Bridge contract on a specific chain | Wormhole governance | \ No newline at end of file diff --git a/products/token-bridge/concepts/transfer-flow.md b/products/token-bridge/concepts/transfer-flow.md new file mode 100644 index 000000000..5ce1b9966 --- /dev/null +++ b/products/token-bridge/concepts/transfer-flow.md @@ -0,0 +1,197 @@ +--- +title: Flow of a Token Bridge Transfer +description: Learn how the Wormhole Token Bridge enables secure, cross-chain token transfers by combining token-specific logic with Wormhole's core message-passing layer. +categories: Token-Bridge, Transfer +--- + +# Flow of a Transfer + +## Introduction + +The [Wormhole Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} enables token transfers across blockchains by combining token-specific logic with [Wormhole's core messaging layer](/docs/protocol/architecture/){target=\_blank}. Each supported chain runs its own Token Bridge contract, which manages actions like locking, burning, minting, and releasing tokens. These contracts communicate directly with Wormhole's core message-passing layer to securely transmit messages between chains. + +This guide provides a conceptual overview of the Token Bridge and its integration with the messaging layer. It outlines each step of the transfer flow and explains how different transfer types work in practice. + +## Transfer Flow + +Cross-chain token transfers using the Token Bridge follow these steps: + +1. **Initiation on the Source Chain** + The transfer begins when a user calls the Token Bridge contract on the source chain: + + - **Wrapped tokens**: The token is burned. + - **Original tokens**: If the token is native to the source chain, the token is locked in the contract. + +2. **Transfer Message Publication** + The Token Bridge contract invokes the Wormhole [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}, which emits an on-chain message event describing the transfer. + +3. **Message Observation and Signing** + [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank}—a decentralized network of validators—monitor the source chain for these message events. A supermajority (13 out of 19) signs the event to generate a [Verified Action Approval (VAA)](/docs/protocol/infrastructure/vaas/){target=\_blank}—a cryptographically signed attestation of the transfer. + + The VAA is then published to the Wormhole network. + +4. **VAA Submission to the Destination Chain** + The VAA must be submitted to the Token Bridge contract on the destination chain to complete the transfer. The Token Bridge contract then verifies the VAA by calling the Core Contract behind the scenes. This step can be handled in two ways: + + - **Automatic**: A relayer service detects the VAA and submits it to the Token Bridge contract. + - **Manual**: The user or dApp retrieves the VAA and submits it directly to the Token Bridge contract. + +5. **Finalization of the Transfer on the Destination Chain** + After the VAA is verified on the destination chain, the Token Bridge contract completes the transfer: + + - **Wrapped tokens**: A wrapped representation of the original token is minted. + - **Original tokens**: If the token is native to the destination chain, the token is released to the recipient. + +Consider this example: Alice wants to send 5 ETH from Ethereum to Solana. The ETH is locked on Ethereum’s Token Bridge, and an equivalent amount of wrapped ETH is minted on Solana. The diagram below illustrates this transfer flow. + +```mermaid +sequenceDiagram + participant Alice as Alice + participant TokenBridgeEth as Token Bridge Ethereum
(Source Chain) + participant CoreEth as Core Contract Ethereum
(Source Chain) + participant Guardians + participant TokenBridgeSol as Token Bridge Solana
(Destination Chain) + participant CoreSol as Core Contract Solana
(Destination Chain) + + Alice->>TokenBridgeEth: Initiate ETH transfer
(lock ETH) + TokenBridgeEth->>CoreEth: Publish transfer message + CoreEth-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA + + alt Automatic VAA submission + Guardians->>TokenBridgeSol: Relayer submits VAA + else Manual VAA submission + Alice->>Guardians: Retrieve VAA + Alice->>TokenBridgeSol: Submit VAA + end + + TokenBridgeSol->>CoreSol: Verify VAA + CoreSol-->>TokenBridgeSol: VAA verified + TokenBridgeSol-->>Alice: Mint wrapped ETH on Solana (complete transfer) +``` + +Maybe Alice wants to transfer her wrapped ETH on Solana back to native ETH on Ethereum. The wrapped ETH is burned on Solana’s Token Bridge, and the equivalent 5 ETH are released on Ethereum. The diagram below illustrates this transfer flow. + +```mermaid +sequenceDiagram + participant User as Alice + participant TokenBridgeSrc as Token Bridge Solana
(Source Chain) + participant CoreSrc as Core Contract Solana
(Source Chain) + participant Guardians + participant TokenBridgeDst as Token Bridge Ethereum
(Destination Chain) + participant CoreDst as Core Contract Ethereum
(Destination Chain) + + User->>TokenBridgeSrc: Initiate transfer
(burn wrapped ETH) + TokenBridgeSrc->>CoreSrc: Publish message + CoreSrc-->>Guardians: Emit message event + Guardians->>Guardians: Sign and publish VAA + + alt Automatic VAA submission + Guardians->>TokenBridgeDst: Relayer submits VAA + else Manual VAA submission + User->>Guardians: Retrieve VAA + User->>TokenBridgeDst: User submits VAA directly + end + + TokenBridgeDst->>CoreDst: Verify VAA + CoreDst-->>TokenBridgeDst: VAA verified + TokenBridgeDst-->>User: Release native ETH on Ethereum (Complete transfer) +``` + + +## Automatic vs. Manual Transfers + +The Token Bridge supports two modes of transfer, depending on whether the VAA submission step is handled automatically or manually: + +- **Automatic**: A relayer service listens for new VAAs and automatically submits them to the destination chain. +- **Manual**: The user (or dApp) must retrieve the VAA and manually submit it to the destination chain. + +Here's a quick breakdown of the key differences: + +| Feature | Automatic Transfer | Manual Transfer | +|---------------------------|-----------------------------|-------------------------------------| +| Who submits the VAA? | Relayer | User or dApp | +| User Experience | Seamless, one-step | Requires manual intervention | +| Best for | End-users, simple UIs | Custom dApps, advanced control | +| Dependency | Requires relayer support | None | + +### Completing Manual Transfers + +The user who initiated the transfer should complete the transfer within 24 hours for manual transfers. Guardian Sets are guaranteed to be valid for at least that long. If a user waits longer, the Guardian Set may have changed between initiation and redemption, causing the VAA to be rejected. + +If this occurs, follow the [Replace Outdated Signatures in VAAs](){target=_blank} tutorial to update the VAA with signatures from the current Guardian Set. + +## Token Bridge Relayer (TBR) + +When completing an automatic transfer using the Token Bridge—either through [Connect](/docs/products/connect/overview/){target=\_blank} or programmatically via the [Wormhole TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}—the Token Bridge Relayer (TBR) manages the interaction with the underlying Token Bridge contracts on [supported chains where the TBR is available](/docs/products/connect/reference/support-matrix/){target=\_blank}. + + + +### Flow of an Automatic Transfer via TBR + +The flow of an automatic transfer using the TBR looks like this: + +1. **Initiation on the Source Chain** + The transfer begins when a user initiates a transfer on the source chain, which results in the TBR contract being called. + +2. **Prepare and Forward the Transfer** + The TBR verifies the token, encodes transfer details (relayer fee, native gas request, recipient), and forwards the transfer to the Token Bridge. + +3. **Core Messaging Layer Processes the Transfer** + The Token Bridge emits a message to the Core Contract. Guardians observe the message and produce a signed VAA attesting to the transfer. + +4. **Off-Chain Relayer Observes the VAA** + + An off-chain relayer verifies the destination chain and token registration and then prepares to complete the transfer. + +5. **Relayer Computes Native Drop-Off and Submits the VAA** + + The relayer queries the destination TBR for the native gas amount, includes it in the transaction, and submits the signed VAA. + +6. **TBR Validates and Completes the Transfer** + + The destination TBR validates the VAA by invoking the Token Bridge contract, confirms it's from a registered TBR, verifies the token and native gas request, and then takes custody of the tokens. + +6. **Asset Distribution on the Destination Chain** + + The TBR sends the remaining tokens and native gas to the user, pays the off-chain relayer fee, and refunds any excess native tokens. + +The following diagram illustrates the key steps on the source chain during a transfer: + +```mermaid +sequenceDiagram + participant User + participant SourceTBR as Source Chain TBR + participant SourceTB as Source Chain Token Bridge + participant Messaging as Core Messaging Layer + + User->>SourceTBR: Initiate transfer (token,
recipient, fees, native gas) + SourceTBR->>SourceTB: Forward transfer (burn or lock tokens) + SourceTB->>Messaging: Publish transfer message +``` + +Once the core messaging layer processes the transfer, the destination chain handles completion as shown below: + +```mermaid +sequenceDiagram + participant Messaging as Core Messaging Layer + participant Relayer as Off-chain Relayer + participant DestTBR as Destination Chain TBR + participant DestTB as Destination Chain
Token Bridge + participant DestUser as User
(Destination Chain) + + Messaging->>Relayer: Emit signed VAA for transfer + Relayer->>Relayer: Verifies destination chain and token registration + Relayer->>DestTBR: Query native gas amount + Relayer->>DestTBR: Submit signed VAA + DestTBR->>DestTB: Validate VAA + DestTBR->>DestTBR: Take custody of tokens + DestTBR->>DestUser: Send tokens (after fees & native gas) + DestTBR->>Relayer: Pay relayer fee & refund excess +``` + +## Next Steps + +Now that you’ve seen how a transfer works try both types yourself to experience the full process: + +- [Get Started with Token Bridge](/docs/products/token-bridge/get-started/){target=\_blank} \ No newline at end of file diff --git a/products/token-bridge/faqs.md b/products/token-bridge/faqs.md new file mode 100644 index 000000000..6e3eef596 --- /dev/null +++ b/products/token-bridge/faqs.md @@ -0,0 +1,36 @@ +--- +title: Token Bridge FAQs +description: Find answers to common questions about the Wormhole Token Bridge, including managing wrapped assets and understanding gas fees. +categories: Token-Bridge, Transfer +--- + +# FAQs + +## Can ownership of wrapped tokens be transferred from the Token Bridge? + +No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. + + - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself + - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge + +The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. + +Relevant contracts: + + - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} + - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} + - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} + +## How do I update the metadata of a wrapped token? + +Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. + +## How do I calculate the current gas costs for Ethereum Mainnet VAA verification? + +You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. + +## How can I update my wrapped token image on Solscan? + +Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. + +To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. diff --git a/products/token-bridge/get-started.md b/products/token-bridge/get-started.md new file mode 100644 index 000000000..436b6626a --- /dev/null +++ b/products/token-bridge/get-started.md @@ -0,0 +1,101 @@ +--- +title: Get Started with Token Bridge +description: Perform token transfers using Wormhole’s Token Bridge with the TypeScript SDK, including manual (Solana–Sepolia) and automatic (Fuji–Alfajores). +categories: Token-Bridge, Transfers +--- + +# Get Started with Token Bridge + +## Introduction + +Wormhole's [Token Bridge](/docs/products/token-bridge/overview){target=\_blank} enables seamless multichain token transfers by locking tokens on a source chain and minting equivalent wrapped tokens on a destination chain. This mechanism preserves token properties such as name, symbol, and decimal precision across chains. + +In this guide, you will use the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} to perform two types of transfers. + + - **Manual transfer**: Where you control each step. + - **Automatic transfer**: Where a relayer finalizes the transfer for you. + +These examples will help you understand how the Token Bridge works across EVM and non-EVM chains. + +## Prerequisites + +Before you begin, make sure you have the following: + + - [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm){target=\_blank} + - Wallets funded with tokens on two [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank} + +This guide uses a Solana wallet with [devnet SOL](https://faucet.solana.com/){target=\_blank} and an EVM wallet with [Sepolia ETH](https://www.alchemy.com/faucets/ethereum-sepolia){target=\_blank} for the manual transfer example, and [Avalanche Fuji](https://core.app/tools/testnet-faucet/?subnet=c&token=c){target=\_blank} and [Celo Alfajores](https://faucet.celo.org/alfajores){target=\_blank} wallets funded with testnet tokens for the automatic transfer. You can adapt the examples to match your preferred chains. + +## Configure Your Token Transfer Environment + +1. Create a new directory and initialize a Node.js project: + + ```bash + mkdir token-bridge + cd token-bridge + npm init -y + ``` + +2. Install the required dependencies: + + ```bash + npm install @wormhole-foundation/sdk + npm install -D tsx typescript + ``` + +3. Create a `transfer.ts` file to handle the multichain transfer logic, and a `helper.ts` file to manage wallet signers and token utilities: + + ```bash + touch transfer.ts helper.ts + ``` + +4. Set up secure access to your wallets. This guide assumes you are loading your `SOL_PRIVATE_KEY` and `EVM_PRIVATE_KEY` from a secure keystore of your choice, such as a secrets manager or a CLI-based tool like [`cast wallet`](https://book.getfoundry.sh/reference/cast/cast-wallet){target=\_blank}. + + !!! warning + If you use a `.env` file during development, add it to your `.gitignore` to exclude it from version control. Never commit private keys or mnemonics to your repository. + +## Perform a Token Transfer + +This section shows how to run manual and automatic token transfers using a shared project structure. You will define helper utilities once and reuse them across both flows. + +In the manual transfer, you initiate a transfer on Solana, wait for Guardian signatures, and redeem the tokens on Sepolia, giving you complete control over each step. In the automatic transfer, the relayer handles attestation and redemption, simplifying the process between EVM chains. + +1. Open `helper.ts` and define utility functions to load private keys, instantiate signers for Solana and EVM chains, and retrieve token decimals as needed: + + ```ts title="helper.ts" + --8<-- "code/products/token-bridge/get-started/snippet-1.ts" + ``` + +2. In `transfer.ts`, add the script for your preferred transfer mode. The `automatic` flag controls transfer behavior passed to `tokenTransfer()`; set it to `false` for manual transfers and `true` for automatic transfers + + === "Manual Transfer" + + ```ts title="transfer.ts" + --8<-- "code/products/token-bridge/get-started/snippet-2.ts" + ``` + + === "Automatic Transfer" + + ```ts title="transfer.ts" + --8<-- "code/products/token-bridge/get-started/snippet-3.ts" + ``` + + +3. Execute the script to initiate and complete the transfer: + + ```bash + npx tsx transfer.ts + ``` + + If successful, the expected output should be similar to this: + + --8<-- "code/products/token-bridge/get-started/snippet-4.html" + +To verify the transaction and view its details, copy the transaction hash from the output and paste it into [Wormholescan](https://wormholescan.io/#/?network=Testnet){target=\_blank}. + +## Next Steps + +Now that you've completed a manual multichain token transfer, explore these guides to continue building: + + - [Complete Token Transfer Workflow](/docs/products/token-bridge/tutorials/transfer-workflow){target=\_blank}: Build a reusable application that supports multiple chain combinations and transfer modes (manual and automatic). + - [Create Multichain Tokens](/docs/products/token-bridge/tutorials/multichain-token){target=\_blank}: Learn how to issue tokens that work across chains. \ No newline at end of file diff --git a/products/token-bridge/guides/.pages b/products/token-bridge/guides/.pages new file mode 100644 index 000000000..52178f6c6 --- /dev/null +++ b/products/token-bridge/guides/.pages @@ -0,0 +1,3 @@ +title: Guides +nav: +- 'Interact with Contracts': token-bridge-contracts.md diff --git a/build/transfers/token-bridge.md b/products/token-bridge/guides/token-bridge-contracts.md similarity index 69% rename from build/transfers/token-bridge.md rename to products/token-bridge/guides/token-bridge-contracts.md index a9ae5ae15..569f3893d 100644 --- a/build/transfers/token-bridge.md +++ b/products/token-bridge/guides/token-bridge-contracts.md @@ -4,20 +4,20 @@ description: Learn how to integrate Wormhole's Token Bridge for seamless multich categories: Token-Bridge, Transfer --- -# Token Bridge +# Interact with Token Bridge Contracts ## Introduction -Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/learn/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. +Wormhole's Token Bridge enables seamless cross-chain token transfers using a lock-and-mint mechanism. The bridge locks tokens on the source chain and mints them as wrapped assets on the destination chain. Additionally, the Token Bridge supports [Token Transfers with Messages](/docs/protocol/infrastructure/vaas/#token-transfer-with-message){target=\_blank}, where arbitrary byte payloads can be attached to the token transfer, enabling more complex chain interactions. -This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} page in the Learn section. +This page outlines the core contract methods needed to integrate Token Bridge functionality into your smart contracts. To understand the theoretical workings of the Token Bridge, refer to the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} page in the Learn section. ## Prerequisites To interact with the Wormhole Token Bridge, you'll need the following: -- [The address of the Token Bridge contract](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with -- [The Wormhole chain ID](/docs/build/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers +- [The address of the Token Bridge contract](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} on the chains you're working with +- [The Wormhole chain ID](/docs/products/reference/chain-ids/){target=\_blank} of the chains you're targeting for token transfers ## How to Interact with Token Bridge Contracts @@ -61,7 +61,7 @@ function attestToken( ??? interface "Example" ```solidity - --8<-- 'code/build/core-messaging/core-contracts/attestToken.sol' + --8<-- 'code/products/token-bridge/guides/token-bridge-contracts/attestToken.sol' ``` When `attestToken()` is called, the contract emits a Verifiable Action Approval (VAA) containing the token's metadata, which the Guardians sign and publish. @@ -125,7 +125,7 @@ function transferTokens( ??? interface "Example" ```solidity - --8<-- 'code/build/core-messaging/core-contracts/transferTokens.sol' + --8<-- 'code/products/token-bridge/guides/token-bridge-contracts/transferTokens.sol' ``` Once a transfer VAA is obtained from the Wormhole Guardian network, the final step is to redeem the tokens on the destination chain. Redemption verifies the VAA's authenticity and releases (or mints) tokens to the specified recipient. To redeem the tokens, call `completeTransfer()`. @@ -201,7 +201,7 @@ function transferTokensWithPayload( ??? interface "Example" ```solidity - --8<-- 'code/build/core-messaging/core-contracts/transferTokensWithPayload.sol' + --8<-- 'code/products/token-bridge/guides/token-bridge-contracts/transferTokensWithPayload.sol' ``` After initiating a transfer on the source chain, the Wormhole Guardian network observes and signs the resulting message, creating a Verifiable Action Approval (VAA). You'll need to fetch this VAA and then call `completeTransferWithPayload()`. @@ -234,34 +234,3 @@ For a deeper understanding of the Token Bridge implementation and to review the ## Portal Bridge A practical implementation of the Wormhole Token Bridge can be seen in [Portal Bridge](https://portalbridge.com/){target=\_blank}, which provides an easy-to-use interface for transferring tokens across multiple blockchain networks. It leverages the Wormhole infrastructure to handle cross-chain asset transfers seamlessly, offering users a convenient way to bridge their assets while ensuring security and maintaining token integrity. - -## FAQs - -### Can ownership of wrapped tokens be transferred from the Token Bridge? - -No, you cannot transfer ownership of wrapped token contracts from the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} because the Token Bridge deploys and retains ownership of these contracts and tokens. - - - **On EVM chains** - when you attest a token, the Token Bridge deploys a new ERC-20 contract as a beacon proxy. The upgrade authority for these contracts is the Token Bridge contract itself - - **On Solana** - the Token Bridge deploys a new SPL token, where the upgrade authority is a Program Derived Address (PDA) controlled by the Token Bridge - -The logic behind deploying these token contracts involves submitting an attestation VAA, which allows the Token Bridge to verify and deploy the wrapped token contract on the destination chain. - -Relevant contracts: - - - [Ethereum ERC-20](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/token/Token.sol){target=\_blank} - - [Solana SPL](https://github.com/wormhole-foundation/wormhole/blob/main/solana/modules/token_bridge/program/src/api/create_wrapped.rs#L128-L145){target=\_blank} - - [Attestation VAA and Token Contract Deployment Logic](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/bridge/Bridge.sol#L385-L431){target=\_blank} - -### How do I update the metadata of a wrapped token? - -Because wrapped tokens are deployed and controlled by the Token Bridge program, which is under the authority of the Wormhole Guardians, there is no direct way for you to update their metadata. Instead, you must coordinate with the respective block explorer teams to request and apply metadata changes. - -### How do I calculate the current gas costs for Ethereum Mainnet VAA verification? - -You can refer to the [core-bridge repository](https://github.com/nonergodic/core-bridge){target=\_blank} for guidance on how to calculate the current gas costs associated with verifying VAAs on Ethereum Mainnet. This repository provides up-to-date references and examples to help you gauge costs accurately. - -### How can I update my wrapped token image on Solscan? - -Updating the metadata (such as the token image, name, or symbol) of a wrapped token on [Solscan](https://solscan.io/){target=\_blank} requires [contacting the Solscan team](https://solscan.io/contactus){target=\_blank} directly. Wormhole cannot make these updates for you because the wrapped token contracts are owned and controlled by the Token Bridge, not individual developers or projects. - -To request an update, contact Solscan via [support@solscan.io](mailto:support@solscan.io) or their [contact form](https://solscan.io/contactus){target=\_blank}. diff --git a/products/token-bridge/overview.md b/products/token-bridge/overview.md new file mode 100644 index 000000000..06449193a --- /dev/null +++ b/products/token-bridge/overview.md @@ -0,0 +1,79 @@ +--- +title: Token Bridge Overview +description: With Wormhole Token Bridge, you can enable secure, multichain communication, build multichain apps, sync data, and coordinate actions across blockchains. +categories: Token-Bridge, Transfer +--- + +# Token Bridge Overview + +The Token Bridge is a Wormhole module for bridging wrapped tokens across various blockchain networks. Locking assets on one network and minting corresponding wrapped tokens on another facilitates secure, efficient, and composable multichain token movement. + +This overview covers Token Bridge's main features, general processes, and possible next steps to begin building a cross-chain application. + +## Key Features + +Token Bridge is built to solve interoperability problems in multichain token transfers. Key features include: + +- **Interoperability**: Transfer standards-compliant tokens (e.g., ERC-20, SPL) across over 30 [supported chains](/docs/products/reference/supported-networks/#token-bridge){target=\_blank}. +- **Lock-and-mint mechanism**: Mint wrapped tokens backed 1:1 by locked assets on the source chain. +- **Preserved metadata**: Ensure that token properties like name, symbol, and decimals persist across chains. +- **Transfer with payload**: Attach arbitrary data to token transfers, enabling the triggering of specific actions. +- **Decentralized security**: Verified by the [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank}, ensuring cross-chain consistency and message authenticity. + +## How It Works + +The Token Bridge provides a reliable foundation for multichain interoperability at scale. The transfer process follows these key steps: + +1. **Attestation**: The token’s metadata (e.g., symbol, name, decimals) is registered on the destination chain. This step is only required once per token. +2. **Locking**: On the source chain, the native token is locked in a custody account. +3. **Message emission**: The [Guardian Network](/docs/protocol/infrastructure/guardians/){target=\_blank} verifies and emits a [VAA](/docs/protocol/infrastructure/vaas/){target=\_blank}. +4. **Verification**: The VAA is submitted and verified on the destination chain to confirm authenticity. +5. **Minting**: A wrapped version of the token is minted (or the native token is released) to the recipient on the destination chain. + +This diagram showcases a simplified flow of Alice bridging ETH from Ethereum to her account on Solana. + +```mermaid +sequenceDiagram + participant Alice + participant Ethereum + participant GuardianNetwork + participant Solana + + Alice->>Ethereum: Lock ETH in Token Bridge contract + Ethereum->>GuardianNetwork: Emit transfer message + GuardianNetwork->>GuardianNetwork: Verify and sign message + + GuardianNetwork->>Solana: Submit signed message + Solana->>Solana: Verify message and mint wrapped ETH (WETH) + + Solana->>Alice: Deliver wrapped ETH on Solana +``` + +For a more in-depth understanding of how the Token Bridge works, see the [Flow of a Transfer](/docs/products/token-bridge/concepts/transfer-flow/){target=\_blank} page. + +## Use Cases + +Here are key use cases that highlight the power and versatility of the Token Bridge. + +- **Multichain Rewards and Token Utility in Decentralized Platforms (e.g., [Chingari](https://chingari.io/){target=\_blank})** + + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Transfer tokens between chains. + - [**Messaging**](/docs/products/messaging/overview/): Facilitate the distribution and claiming processes of rewards. + +- **Tokenized Gaming Rewards** + + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Handle the underlying lock-and-mint logic securely. + - [**Connect**](/docs/products/connect/overview/): Provide a user-friendly way to move game tokens across chains. + +- **Multichain DeFi Arbitrage** + + - [**Token Bridge**](/docs/products/token-bridge/get-started/): Enables rapid and secure movement of DeFi assets. + - [**Connect**](/docs/products/connect/overview/): Provides a UI widget to onboard users and facilitate seamless multichain swaps within DeFi aggregator platforms. + +## Next Steps + +If you are looking for more guided practice, take a look at: + +- [**Get Started with Token Bridge**](/docs/products/token-bridge/get-started/): Perform token transfers using the Token Bridge, including manual and automatic transfers. +- [**Complete Token Transfer Flow**](/docs/products/token-bridge/tutorials/transfer-workflow/): Build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains. +- [**Create Multichain Tokens**](/docs/products/token-bridge/tutorials/multichain-token/): Craft a multichain token using Wormhole's Portal Bridge. \ No newline at end of file diff --git a/products/token-bridge/tutorials/.pages b/products/token-bridge/tutorials/.pages new file mode 100644 index 000000000..cce40e0be --- /dev/null +++ b/products/token-bridge/tutorials/.pages @@ -0,0 +1,4 @@ +title: Tutorials +nav: +- 'Complete Token Transfer Workflow': transfer-workflow.md +- 'Create Multichain Tokens': multichain-token.md \ No newline at end of file diff --git a/tutorials/multichain-assets/multichain-token.md b/products/token-bridge/tutorials/multichain-token.md similarity index 90% rename from tutorials/multichain-assets/multichain-token.md rename to products/token-bridge/tutorials/multichain-token.md index f94710797..3efdb309e 100644 --- a/tutorials/multichain-assets/multichain-token.md +++ b/products/token-bridge/tutorials/multichain-token.md @@ -29,7 +29,7 @@ The first step in creating a multichain token is registering your token on its s 4. Locate the **Asset** field and paste the token contract address 5. Click **Next** to proceed -![Source Chain Registration Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-1.webp) +![Source Chain Registration Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-1.webp) ## Register the Token on the Target Chain @@ -39,7 +39,7 @@ After registering your token on the source chain, the next step is to select the 2. Connect your wallet to the target chain 3. Click **Next** to finalize the registration process -![Target Chain Registration Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-2.webp) +![Target Chain Registration Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-2.webp) ## Send an Attestation Attestation is a key step in the process. It verifies your token’s metadata, ensuring it is correctly recognized on the target chain’s blockchain explorer (e.g., [Etherscan](https://etherscan.io/){target=\_blank}). @@ -47,7 +47,7 @@ Attestation is a key step in the process. It verifies your token’s metadata, e 1. Click **Attest** to initiate the attestation process 2. Approve the transaction in your wallet when prompted -![Send Attestation Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-3.webp) +![Send Attestation Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-3.webp) !!! note - Attestation is crucial for token metadata to appear correctly on blockchain explorers like Etherscan, allowing users to identify and trust your token @@ -60,11 +60,11 @@ The final step is to create the wrapped token on the target chain. This token re 1. Click **Create** to generate the wrapped token 2. Approve the transaction in your wallet when prompted -![Create Wrapped Token Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-4.webp) +![Create Wrapped Token Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-4.webp) Upon successful creation, you will see a confirmation screen displaying key details such as the source chain, target chain, and transaction status. This helps verify that the process was completed correctly. Refer to the image below as an example: -![Confirmation Screen](/docs/images/tutorials/multichain-assets/multichain-tokens/multichain-token-5.webp) +![Confirmation Screen](/docs/images/products/token-bridge/tutorials/multichain-tokens/multichain-token-5.webp) ## Additional Steps and Recommendations diff --git a/tutorials/typescript-sdk/tokens-via-token-bridge.md b/products/token-bridge/tutorials/transfer-workflow.md similarity index 82% rename from tutorials/typescript-sdk/tokens-via-token-bridge.md rename to products/token-bridge/tutorials/transfer-workflow.md index e7c88b3c6..ecee1f16e 100644 --- a/tutorials/typescript-sdk/tokens-via-token-bridge.md +++ b/products/token-bridge/tutorials/transfer-workflow.md @@ -3,13 +3,13 @@ title: Transfer Tokens via Token Bridge Tutorial description: Learn to build a cross-chain native token transfer app using Wormhole’s TypeScript SDK, supporting native token transfers across EVM and non-EVM chains --- -# Transfer Tokens via the Token Bridge +# Complete Token Transfer Workflow :simple-github: [Source code on GitHub](https://github.com/wormhole-foundation/demo-basic-ts-sdk/){target=\_blank} ## Introduction -This tutorial guides you through building a cross-chain token transfer application using the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and its [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} method. The Token Bridge method enables secure and efficient cross-chain asset transfers across different blockchain networks, allowing users to move tokens seamlessly. +This tutorial guides you through building a cross-chain token transfer application using the [Wormhole TypeScript SDK](https://github.com/wormhole-foundation/wormhole-sdk-ts){target=\_blank} and its [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} method. The Token Bridge method enables secure and efficient cross-chain asset transfers across different blockchain networks, allowing users to move tokens seamlessly. By leveraging Wormhole’s Token Bridge, this guide shows you how to build an application that supports multiple transfer types: @@ -33,7 +33,7 @@ Before you begin, ensure you have the following: ## Supported Chains -The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains on the [Contract Addresses](/docs/build/reference/contract-addresses/#token-bridge){target=\_blank} page, which includes every network where Wormhole smart contracts are deployed, across both mainnet and testnet. +The Wormhole SDK supports a wide range of EVM and non-EVM chains, allowing you to facilitate cross-chain transfers efficiently. You can find a complete list of supported chains on the [Contract Addresses](/docs/products/reference/contract-addresses/#token-bridge){target=\_blank} page, which includes every network where Wormhole smart contracts are deployed, across both mainnet and testnet. ## Project Setup @@ -88,7 +88,7 @@ In this section, we’ll guide you through initializing the project, installing 2. Open the `helpers.ts` file and add the following code ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-1.ts" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-1.ts" ``` - **`getEnv`** - this function fetches environment variables like your private key from the `.env` file @@ -113,13 +113,13 @@ In this section, you'll create a script that automates this process by checking 2. **Open `create-wrapped.ts` and import the required modules** - import the necessary SDK modules to interact with Wormhole, EVM, Solana, and Sui chains, as well as helper functions for signing and sending transactions ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:1:6" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:1:6" ``` 3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:8:9" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:8:9" ``` !!! note @@ -128,58 +128,58 @@ In this section, you'll create a script that automates this process by checking 4. **Configure transfer parameters** - specify Arbitrum Sepolia as the source chain and Base Sepolia as the destination, retrieve the token ID from the source chain for transfer, and set the gas limit (optional) ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:12:15" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:12:15" ``` 5. **Set up the destination chain signer** - the signer authorizes transactions, such as submitting the attestation ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:18:18" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:18:18" ``` 6. **Check if the token is wrapped on the destination chain** - verify if the token already exists as a wrapped asset before creating an attestation ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:19:31" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:19:31" ``` - If the token is already wrapped, the script exits, and you may proceed to the [next section](/docs/tutorials/typescript-sdk/tokens-via-token-bridge/#token-transfers). Otherwise, an attestation must be generated. + If the token is already wrapped, the script exits, and you may proceed to the [next section](/docs/products/token-bridge/tutorials/transfer-workflow/#token-transfers). Otherwise, an attestation must be generated. 7. **Set up the source chain signer** - the signer creates and submits the attestation transaction ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:34:34" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:34:34" ``` 8. **Create an attestation transaction** - generate and send an attestation for the token on the source chain to register it on the destination chain, then save the transaction ID to verify the attestation in the next step ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:37:46" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:37:46" ``` 9. **Retrieve the signed VAA** - once the attestation transaction is confirmed, use `parseTransaction(txid)` to extract Wormhole messages, then retrieve the signed VAA from the messages. The timeout defines how long to wait for the VAA before failure ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:49:58" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:49:58" ``` 10. **Submit the attestation on the destination chain** - submit the signed VAA using `submitAttestation(vaa, recipient)` to create the wrapped token on the destination chain, then send the transaction and await confirmation ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:65:70" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:65:70" ``` 11. **Wait for the wrapped asset to be available** - poll until the wrapped token is available on the destination chain ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts:74:88" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts:74:88" ``` If the token is not found, it logs a message and retries after a short delay. Once the wrapped asset is detected, its address is returned. ??? code "Complete script" ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-2.ts" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-2.ts" ``` ### Run the Wrapped Token Creation @@ -209,43 +209,43 @@ Before initiating a cross-chain transfer, you must set up the chain context and 2. Open the `native-transfer.ts` file and begin by importing the necessary modules from the SDK and helper files ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:1:14" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:1:14" ``` 3. **Initialize the Wormhole SDK** - initialize the `wormhole` function for the `Testnet` environment and specify the platforms (EVM, Solana, and Sui) to support ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:15:16" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:15:16" ``` 4. **Set up source and destination chains** - specify the source chain (Sui) and the destination chain (Solana) using the `getChain` method. This allows us to define where to send the native tokens and where to receive them ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:19:20" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:19:20" ``` 5. **Configure the signers** - use the `getSigner` function to retrieve the signers responsible for signing transactions on the respective chains. This ensures that transactions are correctly authorized on both the source and destination chains ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:23:24" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:23:24" ``` 6. **Define the token to transfer** - specify the native token on the source chain (Sui in this example) by creating a `TokenId` object ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:27:27" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:27:27" ``` 7. **Define the transfer amount** - the amount of native tokens to transfer is specified. In this case, we're transferring 1 unit ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:30:30" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:30:30" ``` 8. **Set transfer mode** - specify that the transfer should be manual by setting `automatic = false`. This means you will need to handle the attestation and finalization steps yourself ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:33:33" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:33:33" ``` !!! note @@ -254,19 +254,19 @@ Before initiating a cross-chain transfer, you must set up the chain context and 9. **Define decimals** - fetch the number of decimals for the token on the source chain (Sui) using the `getTokenDecimals` function ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:36:36" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:36:36" ``` 10. **Perform the token transfer and exit the process** - initiate the transfer by calling the `tokenTransfer` function, which we’ll define in the next step. This function takes an object containing all required details for executing the transfer, including the `source` and `destination` chains, `token`, `mode`, and transfer `amount` ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:39:45" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:39:45" ``` Finally, we use `process.exit(0);` to close the script once the transfer completes ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:47:48" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:47:48" ``` ### Token Transfer Logic @@ -278,8 +278,8 @@ This section defines the `tokenTransfer` function, which manages the core steps The `tokenTransfer` function initiates and manages the transfer process, handling all necessary steps to move tokens across chains with the Wormhole SDK. This function uses types from the SDK and our `helpers.ts` file to ensure chain compatibility. ```typescript ---8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:50:61" ---8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:96" +--8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:50:61" +--8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:96" ``` #### Steps to Transfer Tokens @@ -289,19 +289,19 @@ The `tokenTransfer` function consists of several key steps to facilitate the cro 1. **Initialize the transfer object** - the `tokenTransfer` function begins by creating a `TokenTransfer` object, `xfer`, which tracks the state of the transfer process and provides access to relevant methods for each transfer step ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:63:70" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:63:70" ``` 2. **Estimate transfer fees and validate amount** - we obtain a fee quote for the transfer before proceeding. This step is significant in automatic mode (`automatic = true`), where the quote will include additional fees for relaying ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:72:80" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:72:80" ``` 3. **Submit the transaction to the source chain** - initiate the transfer on the source chain by submitting the transaction using `route.source.signer`, starting the token transfer process ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:84:85" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:84:85" ``` - **`srcTxids`** - the resulting transaction IDs are printed to the console. These IDs can be used to track the transfer’s progress on the source chain and [Wormhole network](https://wormholescan.io/#/?network=Testnet){target=\_blank} @@ -319,18 +319,18 @@ The `tokenTransfer` function consists of several key steps to facilitate the cro 4. **Wait for the attestation** - retrieve the Wormhole attestation (VAA), which serves as cryptographic proof of the transfer. In manual mode, you must wait for the VAA before redeeming the transfer on the destination chain ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:90:90" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:90:90" ``` 5. **Complete the transfer on the destination chain** - redeem the VAA on the destination chain to finalize the transfer ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts:94:95" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts:94:95" ``` ??? code "Complete script" ```typescript - --8<-- "code/tutorials/typescript-sdk/tokens-via-token-bridge/token-bridge-3.ts" + --8<-- "code/products/token-bridge/tutorials/transfer-workflow/token-bridge-3.ts" ``` ### Run the Native Token Transfer diff --git a/protocol/.pages b/protocol/.pages new file mode 100644 index 000000000..2f875c919 --- /dev/null +++ b/protocol/.pages @@ -0,0 +1,8 @@ +title: Protocol +nav: +- 'Introduction to Wormhole': introduction.md +- 'Architecture Overview': architecture.md +- 'Ecosystem Overview': ecosystem.md +- 'Security Overview': security.md +- infrastructure +- infrastructure-guides diff --git a/learn/infrastructure/architecture.md b/protocol/architecture.md similarity index 64% rename from learn/infrastructure/architecture.md rename to protocol/architecture.md index 1c775843e..89b9f82c9 100644 --- a/learn/infrastructure/architecture.md +++ b/protocol/architecture.md @@ -10,12 +10,12 @@ categories: Basics Wormhole has several noteworthy components. Before discussing each component in depth, this page will provide an overview of how the major pieces fit together. -![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/learn/infrastructure/architecture/architecture-1.webp) +![Wormhole architecture detailed diagram: source to target chain communication.](/docs/images/protocol/architecture/architecture-1.webp) The preceding diagram outlines the end-to-end flow of multichain communication through Wormhole's architecture, which is described as follows: -1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs -2. **Guardian Network** - [Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} +1. **Source chain** - a source contract emits a message by interacting with the [Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} on the source chain, which publishes the message in the blockchain's transaction logs +2. **Guardian Network** - [Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate these messages and sign them to produce [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} 3. **Relayers** - off-chain relayers or applications fetch the VAA and relay it to the target chain 4. **Target chain** - on the target chain, the message is consumed by the appropriate contract. This contract interacts with the Wormhole Core Contract to verify the VAA and execute the intended multichain operation. @@ -26,18 +26,18 @@ The preceding diagram outlines the end-to-end flow of multichain communication t ## On-Chain Components -- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your [xDapp](/docs/learn/glossary/#xdapp){target=\_blank} or an existing ecosystem protocol -- **[Wormhole Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication +- **Emitter** - a contract that calls the publish message method on the Core Contract. To identify the message, the Core Contract will write an event to the transaction logs with details about the emitter and sequence number. This may be your cross-chain dApp or an existing ecosystem protocol +- **[Wormhole Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank}** - primary contract, this is the contract which the Guardians observe and which fundamentally allows for multichain communication - **Transaction logs** - blockchain-specific logs that allow the Guardians to observe messages emitted by the Core Contract ## Off-Chain Components - **Guardian Network** - validators that exist in their own P2P network. Guardians observe and validate the messages emitted by the Core Contract on each supported chain to produce VAAs (signed messages) -- **[Guardian](/docs/learn/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig -- **[Spy](/docs/learn/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution +- **[Guardian](/docs/protocol/infrastructure/guardians/){target=\_blank}** - one of 19 validators in the Guardian Network that contributes to the VAA multisig +- **[Spy](/docs/protocol/infrastructure/spy/){target=\_blank}** - a daemon that subscribes to messages published within the Guardian Network. A Spy can observe and forward network traffic, which helps scale up VAA distribution - **[API](https://docs.wormholescan.io/){target=\_blank}** - a REST server to retrieve details for a VAA or the Guardian Network -- **[VAAs](/docs/learn/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract -- **[Relayer](/docs/learn/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain +- **[VAAs](/docs/protocol/infrastructure/vaas/){target=\_blank}** - Verifiable Action Approvals (VAAs) are the signed attestation of an observed message from the Wormhole Core Contract +- **[Relayer](/docs/protocol/infrastructure/relayer/){target=\_blank}** - any off-chain process that relays a VAA to the target chain - **Wormhole relayers** - a decentralized relayer network that delivers messages that are requested on-chain via the Wormhole relayer contract - **Custom relayers** - relayers that only handle VAAs for a specific protocol or multichain application. They can execute custom logic off-chain, reducing gas costs and increasing multichain compatibility. Currently, multichain application developers are responsible for developing and hosting custom relayers @@ -51,7 +51,7 @@ The preceding diagram outlines the end-to-end flow of multichain communication t Discover Wormhole's Core Contracts, enabling multichain communication with message sending, receiving, and multicast features for efficient synchronization. - [:custom-arrow: Explore Core Contracts](/docs/learn/infrastructure/core-contracts/) + [:custom-arrow: Explore Core Contracts](/docs/protocol/infrastructure/core-contracts/) - :octicons-tools-16:{ .lg .middle } **Core Messaging** @@ -59,6 +59,6 @@ The preceding diagram outlines the end-to-end flow of multichain communication t Follow the guides in this section to work directly with the building blocks of Wormhole messaging, Wormhole-deployed relayers and Core Contracts, to send, receive, validate, and track multichain messages. - [:custom-arrow: Build with Core Messaging](/docs/build/core-messaging/) + [:custom-arrow: Build with Core Messaging](/docs/products/messaging/guides/wormhole-relayers/)
diff --git a/protocol/ecosystem.md b/protocol/ecosystem.md new file mode 100644 index 000000000..d82981ff6 --- /dev/null +++ b/protocol/ecosystem.md @@ -0,0 +1,34 @@ +--- +title: Ecosystem +description: Explore Wormhole's modular ecosystem of cross-chain tools for messaging, bridging, governance, and developer integration. +categories: Basics +--- + +# The Wormhole Ecosystem + +[Wormhole](/docs/protocol/introduction/){target=\_blank} is a cross-chain messaging protocol connecting decentralized applications across multiple blockchains. It offers a suite of interoperability tools, each addressing different multichain challenges, and allows developers to mix and match these products as needed. + +Whether you’re looking for a simple UI-based bridging experience, a native token transfer flow without wrapped assets, real-time cross-chain data queries, or an advanced settlement layer for complex asset movements, Wormhole has a product designed for that purpose. Every solution integrates with Wormhole’s core messaging network, ensuring each module can operate independently or in combination with others. + +This page will guide you through the structural layout of these tools—how they fit together, can be used independently, and can be layered to build robust, multichain applications. + +## Ecosystem Overview + +The diagram shows a high-level view of Wormhole’s modular stack, illustrating how different tools are grouped into four layers: + +- **Application and user-facing products**: The top layer includes user-centric solutions such as [Connect](/docs/products/connect/overview/){target=\_blank} (a simple bridging interface) and the [NTT Launchpad](https://ntt.wormhole.com/){target=\_blank} (for streamlined native asset deployments). +- **Asset and data transfer layer**: Below it sits the core bridging and data solutions—[NTT](/docs/products/native-token-transfers/overview/){target=\_blank}, [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank}, [Queries](/docs/products/queries/overview/){target=\_blank}, [Settlement](/docs/products/settlement/overview/){target=\_blank}, and [MultiGov](/docs/products/multigov/overview/){target=\_blank}—that handle the movement of tokens, real-time data fetching, advanced cross-chain settlements, and cross-chain governance. +- **Integration layer**: The [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/){target=\_blank}, and [WormholeScan API](https://wormholescan.io/#/){target=\_blank} provide developer-friendly libraries and APIs to integrate cross-chain capabilities into applications. +- **Foundation layer**: At the base, the [Wormhole messaging](/docs/products/messaging/overview/){target=\_blank} system and the [core contracts](/docs/protocol/infrastructure/core-contracts/){target=\_blank} secure the entire network, providing essential verification and cross-chain message delivery. + +![Wormhole ecosystem diagram](/docs/images/protocol/ecosystem/ecosystem-1.webp) + +## Bringing It All Together: Interoperability in Action + +Wormhole’s modularity makes it easy to adopt just the pieces you need. If you want to quickly add bridging to a dApp, use Connect at the top layer while relying on the Foundation Layer behind the scenes. Or if your app needs to send raw messages between chains, integrate the Messaging layer directly via the Integration Layer (TypeScript or Solidity SDK). You can even layer on additional features—like real-time data calls from Queries or more flexible bridging flows with Native Token Transfers. + +Ultimately, these components aren’t siloed but designed to be combined. You could, for instance, fetch a balance from one chain using Queries and then perform an on-chain swap on another chain using Settlement. Regardless of your approach, each Wormhole product is powered by the same Guardian-secured messaging backbone, ensuring all cross-chain interactions remain reliable and secure. + +## Next Steps + +Unsure which bridging solution you need? Visit the [Product Comparison](/docs/products/products/){target=\_blank} page to quickly match your requirements with the right Wormhole tool. diff --git a/protocol/infrastructure-guides/.pages b/protocol/infrastructure-guides/.pages new file mode 100644 index 000000000..c2835f26a --- /dev/null +++ b/protocol/infrastructure-guides/.pages @@ -0,0 +1,4 @@ +title: Infrastructure Guides +nav: +- 'Run a Custom Relayer': run-relayer.md +- 'Run a Spy': run-spy.md diff --git a/build/infrastructure/relayers/run-relayer.md b/protocol/infrastructure-guides/run-relayer.md similarity index 92% rename from build/infrastructure/relayers/run-relayer.md rename to protocol/infrastructure-guides/run-relayer.md index 280eb2a9e..45034a0ff 100644 --- a/build/infrastructure/relayers/run-relayer.md +++ b/protocol/infrastructure-guides/run-relayer.md @@ -21,7 +21,7 @@ This guide teaches you how to set up and configure a custom relayer for efficien To start building a custom relayer, it's essential to grasp the components you'll be managing as part of your relaying service. Your relayer must be capable of retrieving and delivering VAAs.
- ![Custom relayer](/docs/images/build/infrastructure/relayers/run-relayer/relayer-1.webp) + ![Custom relayer](/docs/images/protocol/infrastructure-guides/run-relayer/relayer-1.webp)
The off-chain components outlined in blue must be implemented.
@@ -62,13 +62,13 @@ In the following example, you'll: 3. Start the relayer app ```typescript ---8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-1.ts' +--8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-1.ts' ``` The first meaningful line instantiates the `StandardRelayerApp`, a subclass of the `RelayerApp` with standard defaults. ```typescript ---8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-2.ts' +--8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-2.ts' ``` The only field you pass in the `StandardRelayerAppOpts` is the name to help identify log messages and reserve a namespace in Redis. @@ -78,7 +78,7 @@ The only field you pass in the `StandardRelayerAppOpts` is the name to help iden Other options can be passed to the `StandardRelayerApp` constructor to configure the app further. ```typescript - --8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-3.ts' + --8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-3.ts' ``` The next meaningful line in the example adds a filter middleware component. This middleware will cause the relayer app to request a subscription from the Spy for any VAAs that match the criteria and invoke the callback with the VAA. @@ -86,7 +86,7 @@ The next meaningful line in the example adds a filter middleware component. This If you'd like your program to subscribe to `multiple` chains and addresses, you can call the same method several times or use the `multiple` helper. ```typescript ---8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-4.ts' +--8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-4.ts' ``` The last line in the simple example runs `await app.listen()`, which starts the relayer engine. Once started, the Relayer Engine issues subscription requests to the Spy and begins any other workflows (e.g., tracking missed VAAs). @@ -102,7 +102,7 @@ The source code for this example is available in the [`relayer-engine` repositor Next, you must start a Spy to listen for available VAAs published on the Guardian network. You also need a persistence layer. This example uses Redis. -More details about the Spy are available in the [Spy Documentation](/docs/learn/infrastructure/spy){target=\_blank}. +More details about the Spy are available in the [Spy Documentation](/docs/protocol/infrastructure/spy){target=\_blank}. ### Wormhole Network Spy @@ -153,7 +153,7 @@ docker run --rm -p 6379:6379 --name redis-docker -d redis You can also use the Wormhole SDK to poll the Guardian RPC until a signed VAA is ready using the SDK's `getSignedVAAWithRetry` function. ```ts ---8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-5.ts' +--8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-5.ts' ``` Once you have the VAA, the delivery method is chain-dependent. @@ -163,7 +163,7 @@ Once you have the VAA, the delivery method is chain-dependent. On EVM chains, the bytes for the VAA can be passed directly as an argument to an ABI method. ```ts - --8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-6.ts' + --8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-6.ts' ``` === "Solana" @@ -171,5 +171,5 @@ Once you have the VAA, the delivery method is chain-dependent. On Solana, the VAA is first posted to the core bridge, and then a custom transaction is prepared to process and validate the VAA. ```ts - --8<-- 'code/build/infrastructure/relayers/run-relayer/snippet-7.ts' + --8<-- 'code/protocol/infrastructure-guides/run-relayer/snippet-7.ts' ``` diff --git a/build/infrastructure/spy/run-spy.md b/protocol/infrastructure-guides/run-spy.md similarity index 93% rename from build/infrastructure/spy/run-spy.md rename to protocol/infrastructure-guides/run-spy.md index 61fcb6bef..3a8655d53 100644 --- a/build/infrastructure/spy/run-spy.md +++ b/protocol/infrastructure-guides/run-spy.md @@ -9,7 +9,7 @@ description: Learn how to run a Spy locally to listen for and forward messages ( The Spy is a lightweight component in the Wormhole infrastructure designed to listen for and forward messages (Verifiable Action Approvals (VAAs)) published on the Wormhole network. Running a Spy locally allows developers to subscribe to a filtered stream of these messages, facilitating the development of custom relayers or other integrations with Wormhole. -For a more comprehensive understanding of the Spy and its role within the Wormhole ecosystem, refer to the [Spy Documentation](/docs/learn/infrastructure/spy/){target=\_blank}. +For a more comprehensive understanding of the Spy and its role within the Wormhole ecosystem, refer to the [Spy Documentation](/docs/protocol/infrastructure/spy/){target=\_blank}. ## How to Start a Spy @@ -70,9 +70,6 @@ Once running, a [gRPC](https://grpc.io/){target=\_blank} client (i.e., your prog Use this [proto-spec file](https://github.com/wormhole-foundation/wormhole/blob/main/proto/spy/v1/spy.proto){target=\_blank} to generate a client for the gRPC service. -!!! note - If using JavaScript/TypeScript, the [Spydk](https://www.npmjs.com/package/@certusone/wormhole-spydk){target=\_blank} makes setting up a client easier. - ## Data Persistence The Spy does not have a built-in persistence layer, so it is typically paired with something like Redis or an SQL database to record relevant messages. diff --git a/protocol/infrastructure/.pages b/protocol/infrastructure/.pages new file mode 100644 index 000000000..daf5eef6b --- /dev/null +++ b/protocol/infrastructure/.pages @@ -0,0 +1,7 @@ +title: Infrastructure Components +nav: +- 'Core Contracts': 'core-contracts.md' +- 'VAAs': 'vaas.md' +- 'Guardians': 'guardians.md' +- 'Spy': 'spy.md' +- 'Relayers': 'relayer.md' diff --git a/learn/infrastructure/core-contracts.md b/protocol/infrastructure/core-contracts.md similarity index 87% rename from learn/infrastructure/core-contracts.md rename to protocol/infrastructure/core-contracts.md index 11d6a461c..9eb93872b 100644 --- a/learn/infrastructure/core-contracts.md +++ b/protocol/infrastructure/core-contracts.md @@ -31,7 +31,7 @@ The following describes the role of the Wormhole Core Contract in message transf 2. **Guardian verification** - the Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA 3. **Message reception and execution** - on the target chain, the Wormhole Core Contract receives the verified message, checks the Guardians' signatures, and executes the corresponding actions like minting tokens, updating states, or calling specific smart contract functions -For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/learn/infrastructure/architecture/) page. +For a closer look at how messages flow between chains and all of the components involved, you can refer to the [Architecture Overview](/docs/protocol/architecture/) page. ### Message Submission @@ -39,13 +39,13 @@ You can send multichain messages by calling a function against the source chain - `emitterAddress` - the contract which made the call to publish the message - `sequenceNumber` - a unique number that increments for every message for a given emitter (and implicitly chain) -- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/build/reference/consistency-levels/){target=\_blank} reference page +- `consistencyLevel`- the level of finality to reach before the Guardians will observe and attest the emitted event. This is a defense against reorgs and rollbacks since a transaction, once considered "final," is guaranteed not to have the state changes it caused rolled back. Since different chains use different consensus mechanisms, each one has different finality assumptions, so this value is treated differently on a chain-by-chain basis. See the options for finality for each chain in the [Wormhole Finality](/docs/products/reference/consistency-levels/){target=\_blank} reference page There are no fees to publish a message except when publishing on Solana, but this is subject to change in the future. ### Message Reception -When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/learn/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. +When you receive a multichain message on the target chain Core Contract, you generally must parse and verify the [components of a VAA](/docs/protocol/infrastructure/vaas#vaa-format){target=\_blank}. Receiving and verifying a VAA ensures that the Guardian Network properly attests to the message and maintains the integrity and authenticity of the data transmitted between chains. ## Multicast @@ -53,7 +53,7 @@ Multicast refers to simultaneously broadcasting a single message or transaction This multicast-by-default model makes it easy to synchronize state across the entire ecosystem. A blockchain can make its data available to every chain in a single action with low latency, which reduces the complexity of the n^2 problems encountered by routing data to many blockchains. -This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/learn/transfers/token-bridge/){target=\_blank} and [Wormhole relayer](/docs/learn/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. +This doesn't mean an application _cannot_ specify a destination address or chain. For example, the [Token Bridge](/docs/products/token-bridge/overview/){target=\_blank} and [Wormhole relayer](/docs/protocol/infrastructure/relayer/){target=\_blank} contracts require that some destination details be passed and verified on the destination chain. Because the VAA creation is separate from relaying, the multicast model does not incur an additional cost when a single chain is targeted. If the data isn't needed on a certain blockchain, don't relay it there, and it won't cost anything. @@ -67,7 +67,7 @@ Because the VAA creation is separate from relaying, the multicast model does not Learn about Verified Action Approvals (VAAs) in Wormhole, their structure, validation, and their role in multichain communication. - [:custom-arrow: Learn About VAAs](/docs/learn/infrastructure/vaas/) + [:custom-arrow: Learn About VAAs](/docs/protocol/infrastructure/vaas/) - :octicons-tools-16:{ .lg .middle } **Get Started with Core Contracts** @@ -75,6 +75,6 @@ Because the VAA creation is separate from relaying, the multicast model does not This guide walks through the key methods of the Core Contracts, providing you with the knowledge needed to integrate them into your multichain contracts. - [:custom-arrow: Build with Core Contracts](/docs/build/core-messaging/core-contracts/) + [:custom-arrow: Build with Core Contracts](/docs/products/messaging/guides/core-contracts/)
diff --git a/learn/infrastructure/guardians.md b/protocol/infrastructure/guardians.md similarity index 92% rename from learn/infrastructure/guardians.md rename to protocol/infrastructure/guardians.md index 987767165..b05b81226 100644 --- a/learn/infrastructure/guardians.md +++ b/protocol/infrastructure/guardians.md @@ -14,7 +14,7 @@ Guardians fulfill their role in the messaging protocol as follows: 2. Guardians combine their independent signatures to form a multisig 3. This multisig represents proof that a majority of the Wormhole network has observed and agreed upon a state -Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/learn/infrastructure/vaas/){target=\_blank} (VAAs). +Wormhole refers to these multisigs as [Verifiable Action Approvals](/docs/protocol/infrastructure/vaas/){target=\_blank} (VAAs). ## Guardian Network @@ -54,11 +54,11 @@ This forms the foundation for a purpose-built Proof-of-Authority (PoA) consensus ### Modularity -Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/learn/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. +Wormhole is designed with simple components that are very good at a single function. Separating security and consensus (Guardians) from message delivery ([relayers](/docs/protocol/infrastructure/relayer/){target=\_blank}) allows for the flexibility to change or upgrade one component without disrupting the others. ### Chain Agnosticism -Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/learn/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. +Today, Wormhole supports a broader range of ecosystems than any other interoperability protocol because it uses simple tech (t-schnorr signatures), an adaptable, heterogeneous relayer model, and a robust validator network. Wormhole can expand to new ecosystems as quickly as a [Core Contract](/docs/protocol/infrastructure/core-contracts/){target=\_blank} can be developed for the smart contract runtime. ### Scalability @@ -87,7 +87,7 @@ These principles combine to create a clear pathway towards a fully trustless int Discover the role of relayers in the Wormhole network, including client-side, custom, and Wormhole-deployed types, for secure cross-chain communication. - [:custom-arrow: Learn About Relayers](/docs/learn/infrastructure/relayer/) + [:custom-arrow: Learn About Relayers](/docs/protocol/infrastructure/relayer/) - :octicons-tools-16:{ .lg .middle } **Query Guardian Data** @@ -95,6 +95,6 @@ These principles combine to create a clear pathway towards a fully trustless int Learn how to use Wormhole Queries to add real-time access to Guardian-attested on-chain data via a REST endpoint to your dApp, enabling secure cross-chain interactions and verifications. - [:custom-arrow: Build with Queries](/docs/build/queries/overview/) + [:custom-arrow: Build with Queries](/docs/products/queries/overview/) diff --git a/learn/infrastructure/relayer.md b/protocol/infrastructure/relayer.md similarity index 92% rename from learn/infrastructure/relayer.md rename to protocol/infrastructure/relayer.md index e9f5a2920..3ae2e6eba 100644 --- a/learn/infrastructure/relayer.md +++ b/protocol/infrastructure/relayer.md @@ -8,7 +8,7 @@ categories: Basics This page provides a comprehensive guide to relayers within the Wormhole network, describing their role, types, and benefits in facilitating cross-chain processes. -Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. +Relayers in the Wormhole context are processes that deliver [Verified Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} to their destination, playing a crucial role in Wormhole's security model. They can't compromise security, only availability, and act as delivery mechanisms for VAAs without the capacity to tamper with the outcome. There are three primary types of relayers discussed: @@ -76,7 +76,7 @@ Though simple, this type of relaying is generally not recommended if your aim is Custom relayers are purpose-built components within the Wormhole protocol, designed to relay messages for specific applications. They can perform off-chain computations and can be customized to suit a variety of use cases. -The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/learn/infrastructure/spy/). +The main method of setting up a custom relayer is by listening directly to the Guardian Network via a [Spy](/docs/protocol/infrastructure/spy/). ### Key Features @@ -142,7 +142,7 @@ Developers should note that the choice of relayers depends on their project's sp Discover Wormhole's Spy daemon, which subscribes to gossiped messages in the Guardian Network, including VAAs and Observations, with setup instructions. - [:custom-arrow: Learn More About the Spy](/docs/learn/infrastructure/spy/) + [:custom-arrow: Learn More About the Spy](/docs/protocol/infrastructure/spy/) - :octicons-book-16:{ .lg .middle } **Build with Wormhole Relayers** @@ -150,7 +150,7 @@ Developers should note that the choice of relayers depends on their project's sp Learn how to use Wormhole-deployed relayer configurations for seamless cross-chain messaging between contracts on different EVM blockchains without off-chain deployments. - [:custom-arrow: Get Started with Wormhole Relayers](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Get Started with Wormhole Relayers](/docs/products/messaging/guides/wormhole-relayers/) - :octicons-book-16:{ .lg .middle } **Run a Custom Relayer** @@ -158,6 +158,6 @@ Developers should note that the choice of relayers depends on their project's sp Learn how to build and configure your own off-chain custom relaying solution to relay Wormhole messages for your applications using the Relayer Engine. - [:custom-arrow: Get Started with Custom Relayers](/docs/infrastructure/relayers/run-relayer/) + [:custom-arrow: Get Started with Custom Relayers](/docs/protocol/infrastructure-guides/run-relayer/) diff --git a/learn/infrastructure/spy.md b/protocol/infrastructure/spy.md similarity index 86% rename from learn/infrastructure/spy.md rename to protocol/infrastructure/spy.md index dbf69f9d1..900ed8651 100644 --- a/learn/infrastructure/spy.md +++ b/protocol/infrastructure/spy.md @@ -30,15 +30,15 @@ This monitoring capability is especially beneficial for applications that need i A Spy can access the following categories of messages shared over the gossip protocol: -- [Verifiable Action Approvals (VAAs)](/docs/learn/infrastructure/vaas/){target=\_blank} - packets of multichain data +- [Verifiable Action Approvals (VAAs)](/docs/protocol/infrastructure/vaas/){target=\_blank} - packets of multichain data - The Spy can detect whether a VAA has been approved by the Guardian Network, making it a valuable tool for applications needing real-time multichain verification -- [Observations](/docs/learn/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network +- [Observations](/docs/products/reference/glossary/#observation){target=\_blank} - emitted by Wormhole's core contracts, observations are picked up by the Guardians and relayed across the network - A Spy allow users to monitor these messages, adding transparency and insight into blockchain events -- [Guardian heartbeats](/docs/learn/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status +- [Guardian heartbeats](/docs/products/reference/glossary/#heartbeat){target=\_blank} - heartbeat messages represent Guardian node status - By monitoring heartbeats, a Spy can signal the liveness and connectivity of Guardians in the network @@ -68,7 +68,7 @@ A Spy can access the following categories of messages shared over the gossip pro For an alternative option to on-demand access to Guardian-attested multichain data, see the Wormhole Queries page. Queries provide a simple, REST endpoint style developer experience. - [:custom-arrow: Explore Queries](/docs/build/queries/overview/) + [:custom-arrow: Explore Queries](/docs/products/queries/overview/) @@ -82,7 +82,7 @@ A Spy can access the following categories of messages shared over the gossip pro Learn how to run the needed infrastructure to spin up a Spy daemon locally and subscribe to a stream of Verifiable Action Approvals (VAAs). - [:custom-arrow: Spin Up a Spy](/docs/infrastructure/spy/run-spy/){target=\_blank} + [:custom-arrow: Spin Up a Spy](/docs/protocol/infrastructure-guides/run-spy/){target=\_blank} - :octicons-code-16:{ .lg .middle } **Use Queries** @@ -90,6 +90,6 @@ A Spy can access the following categories of messages shared over the gossip pro For access to real-time network data without infrastructure overhead, follow this guide and use Wormhole Query to construct a query, make a request, and verify the response. - [:custom-arrow: Get Started with Queries](/docs/build/queries/use-queries/) + [:custom-arrow: Get Started with Queries](/docs/products/queries/guides/use-queries/) diff --git a/learn/infrastructure/vaas.md b/protocol/infrastructure/vaas.md similarity index 95% rename from learn/infrastructure/vaas.md rename to protocol/infrastructure/vaas.md index 3740f79df..f59317e95 100644 --- a/learn/infrastructure/vaas.md +++ b/protocol/infrastructure/vaas.md @@ -8,7 +8,7 @@ categories: Basics Verified Action Approvals (VAAs) are Wormhole's core messaging primitive. They are packets of cross-chain data emitted whenever a cross-chain application contract interacts with the Core Contract. -[Guardians](/docs/learn/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. +[Guardians](/docs/protocol/infrastructure/guardians/){target=\_blank} validate messages emitted by contracts before sending them to the target chain. Once a majority of Guardians agree the message is valid, they sign a keccak256 hash of the message body. The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof. @@ -59,7 +59,7 @@ Guardian watchers are specialized processes that monitor each blockchain in real The body of the VAA is hashed twice with `keccak256` to produce the signed digest message. ```js ---8<-- 'code/learn/infrastructure/VAAs/snippet-1.js' +--8<-- 'code/protocol/infrastructure/VAAs/snippet-1.js' ``` !!!tip "Hash vs. double hash" @@ -159,7 +159,7 @@ Governance messages contain pre-defined actions, which can target the various Wo Below is an example message containing a governance action triggering a code upgrade to the Solana Core Contract. The module field here is a right-aligned encoding of the ASCII Core, represented as a 32-byte hex string. ```js ---8<-- 'code/learn/infrastructure/VAAs/snippet-2.js' +--8<-- 'code/protocol/infrastructure/VAAs/snippet-2.js' ``` #### Actions @@ -179,7 +179,7 @@ With the concepts now defined, it is possible to illustrate a full flow for mess 2. **Signatures are aggregated** - Guardians independently observe and sign the message. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA 3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload. The VAA is submitted (or relayed) to the target chain to be processed by a receiving contract and complete the final step -![Lifetime of a message diagram](/docs/images/learn/infrastructure/vaas/lifetime-vaa-diagram.webp) +![Lifetime of a message diagram](/docs/images/protocol/infrastructure/vaas/lifetime-vaa-diagram.webp) ## Next Steps @@ -191,7 +191,7 @@ With the concepts now defined, it is possible to illustrate a full flow for mess Explore Wormhole's Guardian Network, a decentralized system for secure, scalable cross-chain communication across various blockchain ecosystems. - [:custom-arrow: Learn About Guardians](/docs/learn/infrastructure/guardians/) + [:custom-arrow: Learn About Guardians](/docs/protocol/infrastructure/guardians/) - :octicons-tools-16:{ .lg .middle } **Wormhole Relayer** @@ -199,7 +199,7 @@ With the concepts now defined, it is possible to illustrate a full flow for mess Explore this guide to using Wormhole-deployed relayers to send and receive messages using VAAs. - [:custom-arrow: Build with Wormhole Relayer](/docs/build/core-messaging/wormhole-relayers/) + [:custom-arrow: Build with Wormhole Relayer](/docs/products/messaging/guides/wormhole-relayers/) diff --git a/learn/introduction.md b/protocol/introduction.md similarity index 52% rename from learn/introduction.md rename to protocol/introduction.md index a0146c34a..eb7385d05 100644 --- a/learn/introduction.md +++ b/protocol/introduction.md @@ -12,10 +12,10 @@ Wormhole addresses this problem by providing a _generic message-passing_ protoco Wormhole is distinguished by its focus on robust security, scalability, and transparency. The protocol is supported by a decentralized network of validators that ensure the integrity of every cross-chain transaction. This, combined with Wormhole’s proven performance in real-world applications, gives developers a dependable platform to create and scale multichain applications confidently. -![Message-passing process in the Wormhole protocol](/docs/images/learn/introduction/introduction-1.webp) +![Message-passing process in the Wormhole protocol](/docs/images/protocol/introduction/introduction-1.webp) !!! note - The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/learn/infrastructure/architecture/){target=\_blank}. + The above is an oversimplified illustration of the protocol; details about the architecture and components are available on the [architecture page](/docs/protocol/architecture/){target=\_blank}. Wormhole allows developers to leverage the strengths of multiple blockchain ecosystems without being confined to one. This means applications can benefit from the unique features of various networks—such as Solana's high throughput, Ethereum's security, and Cosmos's interoperability while maintaining a unified, efficient user experience. @@ -27,44 +27,44 @@ Interoperability is a critical challenge in the rapidly evolving blockchain land Critical problems Wormhole addresses include: -- **Blockchain isolation** - Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks -- **Cross-chain complexity** - by abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications -- **Security and decentralization** - Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions +- **Blockchain isolation**: Wormhole connects disparate blockchains, enabling the transfer of assets, data, and governance actions across networks. +- **Cross-chain complexity**: By abstracting the complexities of cross-chain communication, Wormhole makes it easier for developers to build and deploy cross-chain applications. +- **Security and decentralization**: Wormhole prioritizes security through a decentralized Guardian network that validates and signs messages, ensuring the integrity of cross-chain interactions. ## What Does Wormhole Offer? Wormhole provides a suite of tools and protocols that support a wide range of use cases: -- **Cross-chain messaging** - securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications (xDapps) -- **Asset transfers** - facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank} -- **Developer tools** - leverage [Wormhole’s SDKs](/docs/build/toolkit/typescript-sdk/){target=\_blank}, [APIs](/docs/build/toolkit/#wormhole-api-docs){target=\_blank}, [Wormhole Scan](https://wormholescan.io/){target=\_blank}, and documentation to build and deploy cross-chain applications quickly and efficiently +- **Cross-chain messaging**: Securely transfer arbitrary data between blockchains, enabling the development of cross-chain decentralized applications. +- **Asset transfers**: Facilitate the movement of tokens and NFTs across supported chains with ease, powered by protocols built on Wormhole like [Portal](https://portalbridge.com/){target=\_blank}. +- **Developer tools**: Leverage Wormhole’s [TypeScript SDK](/docs/tools/typescript-sdk/get-started/){target=\_blank}, [Solidity SDK](/docs/tools/solidity-sdk/get-started/), [Wormholescan](https://wormholescan.io/){target=\_blank}, and the [Wormholescan API](https://wormholescan.io/#/developers/api-doc){target=\_blank} and documentation to build and deploy cross-chain applications quickly and efficiently. ## What Isn't Wormhole? -- **Wormhole is _not_ a blockchain** - it acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself -- **Wormhole is _not_ a token bridge** - while it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge +- **Wormhole is _not_ a blockchain**: It acts as a communication layer that connects different blockchains, enabling them to interact without being a blockchain itself. +- **Wormhole is _not_ a token bridge**: While it facilitates token transfers, Wormhole also supports a wide range of cross-chain applications, making it much more versatile than a typical bridge. ## Use Cases of Wormhole Consider the following examples of potential applications enabled by Wormhole: -- **Cross-chain exchange** - using [Wormhole Connect](/docs/build/transfers/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access -- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}** - NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals -- **Cross-chain game** - games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum +- **Cross-chain exchange**: Using [Wormhole Connect](/docs/products/connect/overview/){target=\_blank}, developers can build exchanges that allow deposits from any Wormhole-connected chain, significantly increasing liquidity access. +- **[Cross-chain governance](https://wormhole.com/blog/stake-for-governance-is-now-live-for-w-token-holders){target=\_blank}**: NFT collections on different networks can use Wormhole to communicate votes cast on their respective chains to a designated "voting" chain for combined proposals +- **Cross-chain game**: Games can be developed on a performant network like Solana, with rewards issued as NFTs on another network, such as Ethereum. ## Explore Discover more about the Wormhole ecosystem, components, and protocols: -- **[Architecture](/docs/learn/infrastructure/architecture/){target=\_blank}** - explore the components of the protocol -- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}** - learn about the protocols built on top of Wormhole +- **[Architecture](/docs/protocol/architecture/){target=\_blank}**: Explore the components of the protocol. +- **[Protocol Specifications](https://github.com/wormhole-foundation/wormhole/tree/main/whitepapers){target=\_blank}**: Learn about the protocols built on top of Wormhole. ## Demos Demos offer more realistic implementations than tutorials: -- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}** - quickly set up a project with the Scaffolding repository -- **[xDapp Book Projects](https://github.com/wormhole-foundation/xdapp-book/tree/main/projects){target=\_blank}** - run and learn from example programs +- **[Wormhole Scaffolding](https://github.com/wormhole-foundation/wormhole-scaffolding){target=\_blank}**: Quickly set up a project with the Scaffolding repository. +- **[Demo Tutorials](https://github.com/wormhole-foundation/demo-tutorials){target=\_blank}**: Explore various demos that showcase Wormhole's capabilities across different blockchains.