Virtual TestNets are live! ⚡️ Test and stage dapps on real-time production data.  Schedule Office Hours

Create Dapp Playground Mode

Dapp Playground Mode


Learn how to run your dapp in playground mode so you can onboard your users gas-free. Allow your users to explore the functionalities of your dapp without spending any money.

To enable playground mode, you need to:

  1. Set up requirements and recommendations.
  2. Create a Tenderly Fork.
  3. Use JSON-RPC as a provider in Ethers.js.
  4. Delete the Fork.

Set up requirements and recommendation

To simplify the integration, we’re going to assume that we use ethers.js to interact with the blockchain. First, we need to add a way for users to enable/disable playground mode, such as a button or any other UI element.

Let’s see a couple of examples.

Create a Tenderly Fork

The first step is to create your Tenderly Fork:

const opts = {
  headers: {
    'X-Access-Key': TENDERLY_ACCESS_KEY as string,
const body = {
  network_id: '1',
  block_number: 14537885,
const resp = await, body, opts);

Fill the user account with Ether

To really showcase the vast functionality of your dapp, it would probably cost some Ether. No worries, you can always give the user an option to “fill” test ETH from our faucet endpoint.

export const fillEther = async (walletAddress: string): Promise<void> => {
  const params = [
    ethers.utils.hexValue(100), // hex encoded wei amount
  await provider.send('tenderly_addBalance', params);

Use JSON-RPC as a provider in Ethers.js

The next step is to use fork.rpc_endpoint as JsonRpcProvider for the ethers.js library.

Spawning Ethers is rather easy:

import { ethers } from 'ethers';
var tenderlyForkProvider = new ethers.providers.JsonRpcProvider(forkURL);

Keep in mind that your dapp has to use tenderlyForkProvider when interacting with a smart contract to have it executed within the Fork:

const contract = new ethers.Contract(CONTADDRESS, CONTRACT_ABI, provider.getSigner());

Delete the Fork

You can choose when to delete your Tenderly Fork. You can do this either when the user turns off the playground mode or after some predefined TTL expires (e.g. 30mins). You have the flexibility to choose depending on your needs.

To delete a Fork, you need to do the following:

const opts = {
  headers: {
    'X-Access-Key': accessKey,
await axios.delete(TENDERLY_FORK_API, opts);

That’s it, we’re done 🎉

Here is the link to the GitHub repo covering this and many other use cases.