Skip to content

Wagmi compatibility hooks #86

@borgbob

Description

@borgbob

Hi

I started working on an alternative frontend which uses this SDK with wagmi/viem. The frontend is part of Avalanche deployment of EAS which is being led by @cryptofish7: https://github.com/avax-attestations/aas-frontend

In the docs I found a link to a gist with some hooks which wrapped wagmi/viem clients in ethers compatible signer/provider, but the code was outdated (it was targeting ethers v5) so I had to adapt it. Here's the updated code which works with ethers v6:

// useProvider.ts
import { JsonRpcProvider, FallbackProvider } from "ethers";
import { type PublicClient } from "viem";
import { useState, useEffect } from "react";
import { usePublicClient } from "wagmi";


function publicClientToProvider(publicClient: PublicClient) {
  const { chain, transport } = publicClient;
  if (!chain) {
    return;
  }

  const network = {
    chainId: chain.id,
    name: chain.name,
    ensAddress: chain.contracts?.ensRegistry?.address
  };

  if (transport.type === "fallback") {
    return new FallbackProvider(
      (transport.transports).map(
        ({ value }: any) => new JsonRpcProvider(value?.url, network)
      )
    );
  }

  return new JsonRpcProvider(transport.url, network);
}

type Provider = ReturnType<typeof publicClientToProvider>

export function useProvider() {
  const publicClient = usePublicClient();
  const [provider, setProvider] = useState<Provider | undefined>(undefined);

  useEffect(() => {
    if (publicClient) {
      setProvider(publicClientToProvider(publicClient));
    }
  }, [publicClient]);

  return provider;
}
// useSigner.ts
import { useEffect, useState } from "react";
import { useWalletClient } from "wagmi";
import { type WalletClient } from "viem";
import { BrowserProvider, JsonRpcSigner } from "ethers";

export async function walletClientToSigner(walletClient: WalletClient) {
  const { account, chain, transport } = walletClient;
  if (!chain || !account) {
    return;
  }

  const network = {
    chainId: chain.id,
    name: chain.name,
    ensAddress: chain.contracts?.ensRegistry?.address
  };

  const provider = new BrowserProvider(transport, network);
  const signer = await provider.getSigner(account.address);

  return signer;
}

export function useSigner() {
  const { data: walletClient } = useWalletClient();

  const [signer, setSigner] = useState<JsonRpcSigner | undefined>(undefined);

  useEffect(() => {
    if (walletClient) {
      walletClientToSigner(walletClient).then((signer) => {
        setSigner(signer);
      })
    }
  }, [walletClient]);

  return signer;
}

If you want, I can create a PR that adds these hooks to a new module (wagmi-compat.ts) so that this functionality is more easily available to SDK users. The module would not be referenced by other modules in this package and users would have to import it directly with something like:

import { useSigner, useProvider } from "@ethereum-attestation-service/eas-sdk/wagmi-compat"

I would also add viem, wagmi and react as peer dependencies.

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