Skip to content

[bug] WalletConnectConnector.getChainId() returns CAIP-2 string, breaks wagmi writeContract #5586

@okwme

Description

@okwme

Description

WalletConnectConnector.getChainId() returns the CAIP-2 network ID (e.g., "eip155:84532") instead of a numeric chain ID. This causes viem's writeContract to fail with:

Cannot convert eip155:84532 to a BigInt

The AuthConnector correctly wraps this with a parseChainId() helper that extracts the numeric portion, but WalletConnectConnector does not.

Steps to Reproduce

  1. Use @reown/appkit-adapter-wagmi v1.8.18+ with wagmi v3
  2. Connect via WalletConnect (or AppKit's embedded wallet)
  3. Call writeContract from @wagmi/core (or useWriteContract from @wagmi/vue / wagmi)
  4. The call fails with Cannot convert eip155:84532 to a BigInt

Root Cause

In WalletConnectConnector (source):

async getChainId() {
  const chainId = ChainController.getActiveCaipNetwork(ConstantsUtil.CHAIN.EVM)?.id;
  // ❌ Returns CAIP network ID like "eip155:84532" directly
  return chainId;
}

In AuthConnector, this is handled correctly:

function parseChainId(chainId) {
  let network = Number(NetworkUtil.parseEvmChainId(chainId));
  // ✅ Extracts numeric chain ID
}

async getChainId() {
  const { chainId } = await provider.getChainId();
  return parseChainId(chainId);  // ✅ Returns numeric
}

wagmi's writeContract internally calls getConnectorClient() which calls connector.getChainId(). The CAIP-2 string is passed to viem, which tries BigInt("eip155:84532") and throws.

Workaround

We bypass wagmi's writeContract entirely by encoding calldata manually and using viem's sendTransaction with chain: null:

import { encodeFunctionData } from 'viem'
import { sendTransaction } from 'viem/actions'
import { getConnectorClient } from '@wagmi/core'

async function writeContract(config, params) {
  const client = await getConnectorClient(config, { chainId })
  const data = encodeFunctionData({
    abi: params.abi,
    functionName: params.functionName,
    args: params.args,
  })
  return sendTransaction(client, {
    to: params.address,
    data,
    chain: null, // Skip chain validation
  })
}

Note: even with getConnectorClient returning a client with the correct numeric chain.id, viem's writeContract still fails because it re-queries the chain from the connector internally.

Expected Fix

WalletConnectConnector.getChainId() should parse the CAIP network ID to extract the numeric chain ID, similar to how AuthConnector does it:

async getChainId() {
  const caipNetworkId = ChainController.getActiveCaipNetwork(ConstantsUtil.CHAIN.EVM)?.id;
  if (caipNetworkId) {
    const parts = String(caipNetworkId).split(':');
    return Number(parts[parts.length - 1]);
  }
  // fallback...
}

Environment

  • @reown/appkit: 1.8.18
  • @reown/appkit-adapter-wagmi: 1.8.18
  • @wagmi/core: 3.4.0
  • @wagmi/vue: 0.1.11
  • viem: 2.46.3
  • Chain: Base Sepolia (84532)
  • Wallet: AppKit embedded wallet via WalletConnect

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions