> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Multichain quickstart

> Create a Multichain Virtual Environment, wire it into Foundry or Hardhat, fund accounts, and run a cross-chain transaction end-to-end.

This tutorial takes you from zero to a cross-chain transaction on a Multichain Virtual Environment. By the end you will have a Virtual Environment that spans more than one network, with the Bridge Module relaying messages between them, your contracts deployed on each network, funded accounts on every chain, and a working cross-chain transaction visible in the unified dashboard timeline.

If you have not read the [overview](/virtual-environments/multichain/overview) yet, do that first. It explains what a Multichain Virtual Environment is, how the RPC URLs are structured, and what Virtual Chain IDs mean.

## Before you begin

You need:

* A Tenderly account with multichain capabilities enabled. If you do not see the option to add multiple networks during Virtual Environment creation, [contact us](https://tenderly.co/contact-us).
* A wallet private key you are willing to use in a test environment. Set it as `PRIVATE_KEY` in your shell.
* [Foundry](https://www.getfoundry.sh/) or [Hardhat](https://hardhat.org/) installed locally.

The rest of the tutorial assumes Ethereum mainnet, Arbitrum, Optimism, and Base, but the same flow works for any combination of supported networks.

## Run the tutorial

<Steps>
  ### Create the Multichain Virtual Environment

  In the Tenderly Dashboard, open **Virtual Environments** and start a new one. Ethereum mainnet is preselected by default. Add Arbitrum, Optimism, and Base from the network picker. Production chains appear first in the list, testnets at the bottom.

  For each network you can choose:

  * **Fork point.** Fork from the latest block (the default) or pick a specific block number, timestamp, or date.
  * **Chain ID.** Leave the default Virtual Chain ID unless you have a reason to override it. The [Virtual Chain IDs](/virtual-environments/multichain/overview#virtual-chain-ids) section explains the tradeoffs.

  Save the Virtual Environment. Take note of the slug Tenderly assigns it. The slug is part of every RPC URL you will use from here on.

  ### Enable the Bridge Module

  Open the Virtual Environment's settings and toggle **Bridging** to On. Once enabled, the Bridge Module watches for cross-chain events on every network in the Virtual Environment and relays them to the destination chain automatically. See [Bridges](/virtual-environments/multichain/bridges) for the protocols and networks it covers.

  ### Wire the RPCs into your project

  Each network in your Virtual Environment has a unique RPC URL with a predictable shape:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  https://virtual.<network>.<region>.rpc.tenderly.co/<org-slug>/<virtual-env-slug>
  ```

  Copy the RPC URLs from the Virtual Environment detail page and add them to your project configuration.

  <Tabs>
    <Tab title="Foundry">
      ```toml title="foundry.toml" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
      [rpc_endpoints]
      mainnet  = "https://virtual.mainnet.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>"
      arbitrum = "https://virtual.arbitrum.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>"
      optimism = "https://virtual.optimism.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>"
      base     = "https://virtual.base.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>"
      ```

      To verify a deployment against the Virtual Environment explorer, set `--verifier-url` to the same RPC. You will get a verified contract in the dashboard the moment the deploy completes.
    </Tab>

    <Tab title="Hardhat">
      ```typescript title="hardhat.config.ts" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
      const config: HardhatUserConfig = {
        networks: {
          tenderly_mainnet: {
            url: "https://virtual.mainnet.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>",
            accounts: [process.env.PRIVATE_KEY],
          },
          tenderly_arbitrum: {
            url: "https://virtual.arbitrum.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>",
            accounts: [process.env.PRIVATE_KEY],
          },
          tenderly_optimism: {
            url: "https://virtual.optimism.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>",
            accounts: [process.env.PRIVATE_KEY],
          },
        },
      };
      ```
    </Tab>
  </Tabs>

  ### Fund accounts on every network

  Open the [Unlimited Faucet](/virtual-environments/unlimited-faucet) for your Virtual Environment and top up the address you will deploy from. Do this on each network, since balances are kept per network. Native currency is enough for the deploy itself. If your contracts move tokens, top those up too.

  ### Deploy and trigger a cross-chain transaction

  Deploy your contracts to each network you attached to the Virtual Environment.

  <Tabs>
    <Tab title="Foundry">
      ```bash showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
      forge create Counter \
        --private-key $PRIVATE_KEY \
        --rpc-url https://virtual.optimism.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug> \
        --broadcast \
        --verify \
        --verifier-url https://virtual.optimism.eu.rpc.tenderly.co/<org-slug>/<virtual-env-slug>
      ```
    </Tab>

    <Tab title="Hardhat">
      ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
      npx hardhat run scripts/deploy.ts --network tenderly_mainnet
      ```
    </Tab>
  </Tabs>

  Once the contracts are deployed on each network, send a cross-chain transaction the way you normally would (for example a LayerZero `send` call). With the Bridge Module on, the destination-side delivery is posted immediately. Open the Virtual Environment dashboard and you should see both the source and destination transactions on the unified timeline.

  Use the [Bridges](/virtual-environments/multichain/bridges#transaction-views) Source/Destination filter to confirm the round-trip explicitly.
</Steps>

You now have a working Multichain Virtual Environment with cross-chain bridging.

## What to try next

Now that the tutorial works, here is how to apply the same setup to real workflows:

<CardGroup cols={2}>
  <Card title="Automate deployments in CI" href="/virtual-environments/ci-cd/github-actions-foundry">
    Deploy to every network on every push, in parallel, using GitHub Actions. The CI/CD guides show the matrix workflow and the secrets you need.
  </Card>

  <Card title="Stage your frontend" href="/virtual-environments/dapp-ui/wagmi">
    Point your dApp at the Virtual Environment RPCs and give your team and reviewers an environment that exercises the full multichain flow.
  </Card>

  <Card title="Create Virtual Environments via API" href="/virtual-environments/develop/create-virtual-environment-via-api">
    The `multivnets` endpoint creates a Multichain Virtual Environment in one call. Useful for per-PR provisioning.
  </Card>

  <Card title="Test bridge failures" href="/virtual-environments/multichain/bridges#manual-bridge-controls">
    Manual bridge controls let you stage gas starvation, duplicate deliveries, modified payloads, and other failure modes deterministically.
  </Card>
</CardGroup>

## See also

* [Multichain Virtual Environments overview](/virtual-environments/multichain/overview)
* [Bridges](/virtual-environments/multichain/bridges)
* [Unlimited Faucet](/virtual-environments/unlimited-faucet)
* [Admin RPC](/virtual-environments/admin-rpc)
