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

# Viem/Wagmi

The popular Viem + Wagmi frontend setup can be used with Sophon. This section will provide a working PoC repository, relevant code snippets, and some cool gotchas that will help you working with this stack.

<Check>
  Check out our simple PoC [repository](https://github.com/sophon-org/hello-paymaster-wagmi-viem) that demonstrates how to use **Viem** and **Wagmi** together with the **Paymaster** .
</Check>

# Using `Viem` with a Paymaster

When building dApps on **Sophon**, it's important to correctly integrate our **Paymaster** to sponsor transactions, especially before **SOPH** is distributed.

This guide provides a working pattern, using `Viem` and `Wagmi`, for sending contract calls with Paymaster support on **Sophon**.

## ✅ Working Code Snippet

```ts theme={null}
"use client";

import { getAccount, getPublicClient, switchChain, writeContract } from "@wagmi/core";
import {
  Abi,
  AbiItemArgs,
  Address,
  createWalletClient,
  custom,
  encodeFunctionData,
  Hash,
  Hex,
} from "viem";
import { Config } from "Wagmi";
import { eip712WalletActions, getGeneralPaymasterInput } from "viem/zksync";
  import { sophonTestnet, sophonMainnet } from "viem/chains";


export default async function sendTransaction(
  wagmiConfig: Config,
  chainId: number,
  address: Address,
  abi: Abi,
  functionName: string,
  args: AbiItemArgs,
  value?: bigint
): Promise<Hash> {
  const account = getAccount(wagmiConfig);

  if (!account.address) throw new Error("No account connected.");
  if (account.chainId !== chainId) await switchChain(wagmiConfig, { chainId });

  const publicClient = getPublicClient(wagmiConfig, { chainId });
  if (!publicClient) throw new Error("No public client available.");

  const estimateGas = await publicClient.estimateContractGas({
    account: account.address,
    address,
    abi,
    functionName,
    args,
    value,
  });

  //   const nextNonce = await publicClient.getTransactionCount({
  //     address: account.address,
  //   });

  // Handle Sophon-specific logic
  if (chainId === 50104 || chainId === 531050104) {
    const walletClient = createWalletClient({
      chain: chainId === 50104 ? sophonMainnet : sophonTestnet
      transport: custom(window.ethereum!),
    }).extend(eip712WalletActions());

    const paymaster: Address = "0x98546B226dbbA8230cf620635a1e4ab01F6A99B2";

    const paymasterInput: Hex = getGeneralPaymasterInput({
      innerInput: "0x",
    });

    const txData = encodeFunctionData({ abi, functionName, args });

    const hash = await walletClient.sendTransaction({
      account: account.address,
      to: address,
      data: txData,
      value,
      gas: estimateGas,
      chain,
      paymaster,
      paymasterInput,
      //   nonce: nextNonce, enable if you want to use a specific nonce
    });

    return hash;
  }

  // Fallback for non-ZKsync chains
  return await writeContract(wagmiConfig, {
    address,
    chainId,
    abi,
    functionName,
    args,
    value,
    gas: estimateGas,
  });
}
```

## **⚠️ Key Gotchas to Watch Out For**

### **1. Missing paymasterInput or incorrect format**

`paymasterInput` **must** be passed, even if it’s an empty `0x` using:

```
getGeneralPaymasterInput({ innerInput: "0x" }).
```

<Warning>
  Manually hardcoding `paymasterInput = "0x"` will not work.
</Warning>

### **2. Use ZKsync wallet extensions**

Extend your wallet client with `eip712WalletActions()` to support `sendTransaction` with Paymasters.

```typescript theme={null}
const walletClient = createWalletClient({
      chain: sophonTestnet, // or `sophonMainnet`
      transport: custom(window.ethereum!),
    }).extend(eip712WalletActions());
```

### **3. Pre-calculating the nonce is possible, but optional**

Based on your personal use-cases, you can pre-calculate nonces, but this is also handled internally by Wagmi's `publicClient` **provider wrapper**.

```typescript theme={null}
const publicClient = getPublicClient(wagmiConfig, { chainId });

 const nextNonce = await publicClient.getTransactionCount({
      address: account.address,
    });

const hash = await walletClient.sendTransaction({
      account: account.address,
      to: address,
      data: txData,
      value,
      gas: estimateGas,
      chain: sophonTestnet, // chain client that is connected
      paymaster,
      paymasterInput,
      nonce: nextNonce,
    });
```
