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

# Interact with Contracts

> Read and write smart contract data and handle events using Web3 libraries on React Native

Read data from smart contracts and execute write operations using Para's wallet infrastructure.

<Card title="Setup EVM Libraries First" description="Install and configure Ethers.js or Viem before using EVM operations" href="/v3/react-native/guides/web3-operations/evm/setup-libraries" horizontal />

<Info>
  Sepolia examples need testnet ETH before writing contracts. Get `requestFaucetAsync` from `useRequestFaucet()` and call `requestFaucetAsync({ chain: "ETHEREUM_SEPOLIA" })` after the user has an EVM wallet. If `chain` is omitted, the faucet defaults to `ETHEREUM_SEPOLIA`. See [Fund Testnet Wallet](/v3/react-native/guides/web3-operations/evm/fund-testnet-wallet) for the full example.
</Info>

<Note>
  Wagmi is not available on React Native. Use Ethers.js or Viem for EVM operations.
</Note>

<Tabs>
  <Tab title="Ethers.js">
    ## Read Contract Data

    ```typescript theme={null}
    import { ethers } from "ethers";

    const CONTRACT_ABI = [
      "function balanceOf(address owner) view returns (uint256)",
      "function totalSupply() view returns (uint256)",
      "function name() view returns (string)",
      "function symbol() view returns (string)",
      "function decimals() view returns (uint8)"
    ];

    async function readContractData(
      provider: ethers.Provider,
      contractAddress: string,
      userAddress: string
    ) {
      const contract = new ethers.Contract(
        contractAddress,
        CONTRACT_ABI,
        provider
      );

      const [balance, totalSupply, name, symbol, decimals] = await Promise.all([
        contract.balanceOf(userAddress),
        contract.totalSupply(),
        contract.name(),
        contract.symbol(),
        contract.decimals()
      ]);

      return {
        balance: ethers.formatUnits(balance, decimals),
        totalSupply: ethers.formatUnits(totalSupply, decimals),
        name,
        symbol,
        decimals
      };
    }
    ```

    ## Write Contract Data

    ```typescript theme={null}
    const STAKING_ABI = [
      "function stake(uint256 amount) payable",
      "function unstake(uint256 amount)",
      "function getStakedBalance(address user) view returns (uint256)",
      "event Staked(address indexed user, uint256 amount)",
      "event Unstaked(address indexed user, uint256 amount)"
    ];

    async function stakeTokens(
      signer: any,
      contractAddress: string,
      amount: string,
      decimals: number
    ) {
      const contract = new ethers.Contract(contractAddress, STAKING_ABI, signer);
      const parsedAmount = ethers.parseUnits(amount, decimals);

      const tx = await contract.stake(parsedAmount);
      await tx.wait();

      const newBalance = await contract.getStakedBalance(await signer.getAddress());

      return {
        hash: tx.hash,
        stakedAmount: ethers.formatUnits(newBalance, decimals)
      };
    }
    ```
  </Tab>

  <Tab title="Viem">
    ## Read Contract Data

    Read operations don't need mutation helpers -- use the Viem `publicClient` directly:

    ```typescript theme={null}
    import { createPublicClient, http, formatUnits } from "viem";
    import { sepolia } from "viem/chains";

    const CONTRACT_ABI = [
      {
        name: "balanceOf",
        type: "function",
        stateMutability: "view",
        inputs: [{ name: "owner", type: "address" }],
        outputs: [{ type: "uint256" }],
      },
      {
        name: "totalSupply",
        type: "function",
        stateMutability: "view",
        inputs: [],
        outputs: [{ type: "uint256" }],
      },
      {
        name: "name",
        type: "function",
        stateMutability: "view",
        inputs: [],
        outputs: [{ type: "string" }],
      },
      {
        name: "symbol",
        type: "function",
        stateMutability: "view",
        inputs: [],
        outputs: [{ type: "string" }],
      },
      {
        name: "decimals",
        type: "function",
        stateMutability: "view",
        inputs: [],
        outputs: [{ type: "uint8" }],
      },
    ] as const;

    const publicClient = createPublicClient({
      chain: sepolia,
      transport: http(),
    });

    async function readContractData(
      contractAddress: `0x${string}`,
      userAddress: `0x${string}`
    ) {
      const results = await publicClient.multicall({
        contracts: [
          {
            address: contractAddress,
            abi: CONTRACT_ABI,
            functionName: "balanceOf",
            args: [userAddress],
          },
          {
            address: contractAddress,
            abi: CONTRACT_ABI,
            functionName: "totalSupply",
          },
          {
            address: contractAddress,
            abi: CONTRACT_ABI,
            functionName: "name",
          },
          {
            address: contractAddress,
            abi: CONTRACT_ABI,
            functionName: "symbol",
          },
          {
            address: contractAddress,
            abi: CONTRACT_ABI,
            functionName: "decimals",
          },
        ],
      });

      const [balance, totalSupply, name, symbol, decimals] = results.map(
        (r) => r.result
      );

      return {
        balance: formatUnits(balance, decimals),
        totalSupply: formatUnits(totalSupply, decimals),
        name,
        symbol,
        decimals,
      };
    }
    ```

    ## Write Contract Data

    ```tsx theme={null}
    import { useParaViemClient, useParaViemWriteContract } from "@getpara/react-native-wallet/evm/viem";
    import { parseUnits, http } from "viem";
    import { sepolia } from "viem/chains";
    import { View, Text, TouchableOpacity } from "react-native";

    const STAKING_ABI = [
      {
        name: "stake",
        type: "function",
        stateMutability: "payable",
        inputs: [{ name: "amount", type: "uint256" }],
        outputs: [],
      },
    ] as const;

    function StakeTokens({
      contractAddress,
      decimals = 18,
    }: {
      contractAddress: `0x${string}`;
      decimals?: number;
    }) {
      const amount = "100";

      const { viemClient } = useParaViemClient({
        walletClientConfig: { chain: sepolia, transport: http() },
      });

      const { writeContractAsync, isPending, data: hash } = useParaViemWriteContract(viemClient);

      return (
        <View>
          <TouchableOpacity
            onPress={() =>
              writeContractAsync({
                address: contractAddress,
                abi: STAKING_ABI,
                functionName: "stake",
                args: [parseUnits(amount, decimals)],
              })
            }
            disabled={isPending}
          >
            <Text>{isPending ? "Staking..." : `Stake ${amount} Tokens`}</Text>
          </TouchableOpacity>
          {hash && <Text>Transaction: {hash}</Text>}
        </View>
      );
    }
    ```
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={3}>
  <Card title="Watch Events" description="Subscribe to and filter contract events" href="/v3/react-native/guides/web3-operations/evm/watch-events" icon="eye" />

  <Card title="Manage Allowances" description="Handle token approvals and allowances" href="/v3/react-native/guides/web3-operations/evm/manage-allowances" icon="shield-check" />

  <Card title="Get Transaction Receipt" description="Parse transaction logs and events" href="/v3/react-native/guides/web3-operations/evm/get-transaction-receipt" icon="receipt" />
</CardGroup>
