Skip to content

Instantly share code, notes, and snippets.

@slavik0329
Created August 10, 2023 15:31
Show Gist options
  • Save slavik0329/2e5b6fc31cb745b65d3d37f7cf1d7b36 to your computer and use it in GitHub Desktop.
Save slavik0329/2e5b6fc31cb745b65d3d37f7cf1d7b36 to your computer and use it in GitHub Desktop.
import { type PublicClient, type WalletClient } from "@wagmi/core";
import { providers } from "ethers";
import { type HttpTransport } from "viem";
import { useEffect, useState } from "react";
import type { JsonRpcProvider, JsonRpcSigner } from "@ethersproject/providers";
import { usePublicClient, useWalletClient } from "wagmi";
export function publicClientToProvider(publicClient: PublicClient) {
const { chain, transport } = publicClient;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address
};
if (transport.type === "fallback")
return new providers.FallbackProvider(
(transport.transports as ReturnType<HttpTransport>[]).map(
({ value }) => new providers.JsonRpcProvider(value?.url, network)
)
);
return new providers.JsonRpcProvider(transport.url, network);
}
export function walletClientToSigner(walletClient: WalletClient) {
const { account, chain, transport } = walletClient;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address
};
const provider = new providers.Web3Provider(transport, network);
const signer = provider.getSigner(account.address);
return signer;
}
export function useSigner() {
const { data: walletClient } = useWalletClient();
const [signer, setSigner] = useState<JsonRpcSigner | undefined>(undefined);
useEffect(() => {
async function getSigner() {
if (!walletClient) return;
const tmpSigner = walletClientToSigner(walletClient);
setSigner(tmpSigner);
}
getSigner();
}, [walletClient]);
return signer;
}
export function useProvider() {
const publicClient = usePublicClient();
const [provider, setProvider] = useState<JsonRpcProvider | undefined>(undefined);
useEffect(() => {
async function getSigner() {
if (!publicClient) return;
const tmpProvider = publicClientToProvider(publicClient);
setProvider(tmpProvider as JsonRpcProvider);
}
getSigner();
}, [publicClient]);
return provider;
}
@Rashmi-278
Copy link

Rashmi-278 commented Apr 25, 2024

Here's a similar utils file that works for me in CRA, https://gist.github.com/Rashmi-278/8728ff58e50d043c98ac1ef9612ff1df

ethers 5.7.2

@Koushith
Copy link

Koushith commented Aug 6, 2024

TLDR;

https://wagmi.sh/react/guides/ethers

import {
  BrowserProvider,
  FallbackProvider,
  JsonRpcProvider,
  JsonRpcSigner,
} from "ethers";
import { useMemo } from "react";
import type { Account, Chain, Client, Transport } from "viem";
import { type Config, useClient, useConnectorClient } from "wagmi";

export function clientToProvider(client: Client<Transport, Chain>) {
  const { chain, transport } = client;
  const network = {
    chainId: chain.id,
    name: chain.name,
    ensAddress: chain.contracts?.ensRegistry?.address,
  };
  if (transport.type === "fallback") {
    const providers = (transport.transports as ReturnType<Transport>[]).map(
      ({ value }) => new JsonRpcProvider(value?.url, network)
    );
    if (providers.length === 1) return providers[0];
    return new FallbackProvider(providers);
  }
  return new JsonRpcProvider(transport.url, network);
}

export function clientToSigner(client: Client<Transport, Chain, Account>) {
  const { account, chain, transport } = client;
  const network = {
    chainId: chain.id,
    name: chain.name,
    ensAddress: chain.contracts?.ensRegistry?.address,
  };
  const provider = new BrowserProvider(transport, network);
  const signer = new JsonRpcSigner(provider, account.address);
  return signer;
}

/** Action to convert a viem Client to an ethers.js Provider. */
export function useEthersProvider({ chainId }: { chainId?: number } = {}) {
  const client = useClient<Config>({ chainId });
  return useMemo(
    () => (client ? clientToProvider(client) : undefined),
    [client]
  );
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
function useEthersSigner({ chainId }: { chainId?: number } = {}) {
  const { data: client } = useConnectorClient<Config>({ chainId });
  return useMemo(() => (client ? clientToSigner(client) : undefined), [client]);
}

export { useEthersSigner };

@LindaJatique
Copy link

this might be outdated...i am getting a lot of typescript errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment