dApp Playground Mode

Overview

Onboarding users to the dApp application is really hard. You cannot showcase the functionality without actually spending user money. But what if you could?
We are going to take a look at how you can spin up a playground mode of your dApp where users interact with it without actually spending any real funds.
Letโ€™s see what needs to be done in order to enable playground mode:
  1. 1.
    Setup requirements and recommendations.
  2. 2.
    Create a Tenderly Fork.
  3. 3.
    Use JSON RPC as a provider in Ethers.js.
  4. 4.
    Delete the Fork.

Setup requirements and recommendation

In order to simplify the integration, we are going to assume that we use ethers.js for interactions with the blockchain. The first step is to add some way for users to enable/disable playground mode - you can imagine it as a button or any other UI element.
Letโ€™s see a couple of examples of how this can look.

Create a Tenderly Fork

The first step is to create your Tenderly Fork:
1
const { TENDERLY_USER, TENDERLY_PROJECT, TENDERLY_ACCESS_KEY } = process.env;
2
const TENDERLY_FORK_API = `http://api.tenderly.co/api/v1/account/${TENDERLY_USER}/project/${TENDERLY_PROJECT}/fork`;
3
โ€‹
4
const opts = {
5
headers: {
6
'X-Access-Key': TENDERLY_ACCESS_KEY as string,
7
}
8
}
9
const body = {
10
"network_id": "1",
11
"block_number": 14537885,
12
}
13
โ€‹
14
const resp = await axios.post(TENDERLY_FORK_API, body, opts);
Copied!

Fill user account with Ether

To really showcase the vast functionality of your dApp it would probably cost a bit of Ether. No worries, as you can always give the User an option to โ€œFillโ€ ethers from our faucet endpoint.
1
export const fillEther = async (walletAddress: string): Promise<void> => {
2
const params = [
3
[walletAddress],
4
ethers.utils.hexValue(100) // hex encoded wei amount
5
];
6
โ€‹
7
await provider.send('tenderly_addBalance', params)
8
}
Copied!

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:
1
import {ethers} from "ethers"
2
โ€‹
3
var tenderlyForkProvider = new ethers.providers.JsonRpcProvider(forkURL);
Copied!
Keep in mind that your app has to use tenderlyForkProvider when interacting with the smart contract in order to have them executed within the fork:
1
const contract = new ethers.Contract(CONTADDRESS , CONTRACT_ABI , provider.getSigner());
Copied!

Delete the Fork

You can choose when you would like to Delete your Tenderly Fork - either when the user turns off the playground mode or after some predefined TTL expires (e.g. 30mins), this part is up to you. But, letโ€™s see how this is done:
1
const TENDERLY_FORK_ACCESS_URL = `https://api.tenderly.co/api/v1/account/${TENDERLY_USER}/project/${TENDERLY_PROJECT}/fork/${forkId}`
2
const opts = {
3
headers: {
4
'X-Access-Key': accessKey,
5
}
6
}
7
โ€‹
8
await axios.delete(TENDERLY_FORK_API, opts);
Copied!
That's it, we are done ๐ŸŽ‰
Here is the link to the GitHub repo covering this and many other use-cases.