> ## 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.

# Viem

> Connect viem to a Virtual Environment to define a custom chain, call standard and custom RPC methods, and simulate or trace transactions.

[Viem](https://viem.sh/) is a TypeScript Interface for Ethereum that provides low-level stateless primitives for interacting with Ethereum.

You can interact with Virtual Environments using the standard RPC methods when you copy the **Public RPC**,
as well as [custom methods available on Node RPC](/virtual-environments/admin-rpc) when you copy the **Admin RPC**.

<Card title="Code samples: Using Viem with Virtual Environments" href="" />

## Define a custom chain

Create a file `tenderly.config.ts` and use **`defineChain`** to create a chain object.

<Info>
  If you specified a unique Chain ID during Virtual Environment creation, you need to create a new chain object and set the **`id`** to your chosen value.
</Info>

```typescript title="virtual-environments/src/tenderly.config.ts" showLineNumbers lines={4, 8, 13} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

export const vMainnet = defineChain({
  id: 73571,
  name: 'Virtual Ethereum Mainnet',
  nativeCurrency: { name: 'vEther', symbol: 'vETH', decimals: 18 },
  rpcUrls: {
    default: { http: [process.env.TENDERLY_VIRTUAL_MAINNET_RPC!] },
  },
  blockExplorers: {
    default: {
      name: 'Tenderly Explorer',
      url: process.env.TENDERLY_VIRTUAL_MAINNET_EXPLORER!
    },
  },
  contracts: {
    ensRegistry: {
      address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
    },
    ensUniversalResolver: {
      address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da',
      blockCreated: 16773775,
    },
    multicall3: {
      address: '0xca11bde05977b3631167028862be2a173976ca11',
      blockCreated: 14353601,
    },
  },
});
```

## Define Viem actions for custom RPC methods

Define Viem actions for custom RPC methods, such as `tenderly_setBalance` `tenderly_setErc20Balance`, and `simulate`.

For example, the following file defines a `tenderlySetBalance` action that will invoke `tenderly_setBalance`.

You can find more actions here:

<Card title="Viem actions for custom RPC methods" href="" />

```typescript title="virtual-environments/src/viem-tenderly-actions.ts" theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

type TSetBalanceParams = [addresses: Hex[], value: Hex];

export async function tenderlySetBalance(client: Client, params: TSetBalanceParams) {
  return client.request<{
    method: 'tenderly_setBalance',
    Parameters: TSetBalanceParams,
    ReturnType: Hex
  }>({
    method: 'tenderly_setBalance',
    params: params,
  });
}
```

## Call standard and custom RPC methods

In this example, you can see how to:

* Call Viem's `createPublicClient` and pass the following arguments:
* **`chain`**: set to `vMainnet` we defined in the previous step
* **`transport`**: either a call to `http`, and set to `https` RPC URL.

```typescript title="virtual-environments/src/viem-call-balance-top-up.ts" showLineNumbers {8, 12-13, 24-28, 31-34, 39-41, 46} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

(async () => {
  const client = createPublicClient({
    chain: vMainnet,
    transport: http(vMainnet.rpcUrls.default.http[0]),
  });

  console.log("Block Number", await client.getBlockNumber());
  console.log("Chain", await client.getChainId());

  const balanceTxs = await Promise.all([
    tenderlySetBalance(client, [
      ["0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"],
      "0xDE0B6B3A7640000"
    ]),
    tenderlySetErc20Balance(client, [
      "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "0x40BdB4497614bAe1A67061EE20AAdE3c2067AC9e",
      "0xDE0B6B3A7640000"
    ]),
    // USDT
    tenderlySetErc20Balance(client, [
      "0x6B175474E89094C44Da98b954EedeAC495271d0F",
      "0x40BdB4497614bAe1A67061EE20AAdE3c2067AC9e",
      "0xDE0B6B3A7640000"
    ]),
    tenderlySetErc20Balance(client, [
      "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
      "0x40BdB4497614bAe1A67061EE20AAdE3c2067AC9e",
      "0xDE0B6B3A7640000"
    ]),
  ]);

  console.log(
    "ETH balance, DAI and ShibaInu topups",
    balanceTxs.map(txHash => `${(vMainnet.blockExplorers.default.url)}/tx/${txHash}`));
})().catch(e => {
  console.error(e);
  process.exitCode = 1;
});
```

## Simulate transactions using viem

To use Virtual Environment's [Simulation RPC methods](/node-rpc/rpc-reference?network=ethereum-mainnet\&method=tenderly_simulateTransaction), simply `request` to make the call to **`tenderly_simulateTransaction`**:

```typescript title="virtual-environments/src/viem-call-simulate.ts" showLineNumbers {6, 9-24} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

const client = createPublicClient({
  chain: vMainnet,
  transport: http(vMainnet.rpcUrls.default[0])
});

const simulation = await client.request({
  method: "tenderly_simulateTransaction",
  params: [
    // transaction object
    {
      from: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      to: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      gas: "0x0",
      gasPrice: "0x0",
      value: "0x0",
      data: "0xa9059cbb00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001",
    },
    // the block
    "latest",
  ],
});

console.log("Trace");
console.log(JSON.stringify(simulation.trace, null, 2));
console.log("Logs");
console.log(JSON.stringify(simulation.logs, null, 2));
console.log("Asset Changes");
console.log(JSON.stringify(simulation.assetChanges, null, 2));
console.log("Balance Changes");
console.log(JSON.stringify(simulation.balanceChanges, null, 2));
```

## Trace transactions using Viem

Use [`tenderly_traceTransaction`](/node-rpc/rpc-reference?network=ethereum-mainnet\&method=tenderly_traceTransaction) to get fully decoded transaction trace.

```ts showLineNumbers title="node/samples/viem/2-transaction-trace.ts" {2-6} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const txTrace = await client.request({
  method: "tenderly_traceTransaction",
  params: [
    // transaction hash
    "0x6b2264fa8e28a641d834482d250080b39cbbf39251344573c7504d6137c4b793"
  ],
});


console.log("Logs");
console.log(JSON.stringify(txTrace.logs, null, 2));
console.log("=======================================================");
console.log("Asset Changes");
console.log(JSON.stringify(txTrace.assetChanges, null, 2));
console.log("=======================================================");
console.log("Balance Changes");
console.log(JSON.stringify(txTrace.balanceChanges, null, 2));
console.log("=======================================================");
```
