Skip to content

Commit

Permalink
docs: ethers adapters reference implementation (#2563)
Browse files Browse the repository at this point in the history
* docs: ethers adapters reference implementation

* trigger

* docs: update
  • Loading branch information
jxom committed Jun 18, 2023
1 parent 4ad7c05 commit 912adb2
Show file tree
Hide file tree
Showing 5 changed files with 349 additions and 3 deletions.
3 changes: 2 additions & 1 deletion docs/pages/core/_meta.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
"getting-started": "Getting Started",
"migration-guide": "Migration Guide",
"typescript": "TypeScript",
"config": "Config",
"config": "createConfig",
"chains": "Chains",
"providers": "Providers",
"connectors": "Connectors",
"actions": "Actions",
"constants": "Constants",
"ethers-adapters": "Ethers.js Adapters",
"module-types": "Module Types",
"faq": "FAQ"
}
168 changes: 168 additions & 0 deletions docs/pages/core/ethers-adapters.en-US.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
title: 'Ethers.js Adapters'
description: 'Adapters for ethers.js'
---

import { Tabs, Tab } from 'nextra-theme-docs'

# Ethers.js Adapters

It is recommended for projects to migrate to [viem](https://viem.sh) when using wagmi, but there are some cases where you might still need to use [ethers.js](https://ethers.org/) in your project:

- You may want to **incrementally migrate** ethers.js usage to viem
- Some **third-party libraries & SDKs** may only support ethers.js

We have provided reference implementations for viem → ethers.js adapters that you can copy + paste in your project.

## Public Client → Provider

### Reference Implementation

Copy the following reference implementation into a file of your choice:

<Tabs items={['ethers.js v5', 'ethers.js v6']}>
<Tab>
```ts filename="src/ethers.ts"
import { type PublicClient, getPublicClient } from '@wagmi/core'
import { providers } from 'ethers'
import { type HttpTransport } from 'viem'

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)
}

/** Action to convert a viem Public Client to an ethers.js Provider. */
export function getEthersProvider({ chainId }: { chainId?: number } = {}) {
const publicClient = getPublicClient({ chainId })
return publicClientToProvider(publicClient)
}
```
</Tab>
<Tab>
```ts filename="src/ethers.ts"
import { type PublicClient, getPublicClient } from '@wagmi/core'
import { FallbackProvider, JsonRpcProvider } from 'ethers'
import { type HttpTransport } from 'viem'

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') {
const providers = (transport.transports as ReturnType<HttpTransport>[]).map(
({ value }) => new JsonRpcProvider(value?.url, network),
)
if (providers.length === 1) return providers[0]
return new FallbackProvider(providers)
}
return new JsonRpcProvider(transport.url, network)
}

/** Action to convert a viem Public Client to an ethers.js Provider. */
export function getEthersProvider({ chainId }: { chainId?: number } = {}) {
const publicClient = getPublicClient({ chainId })
return publicClientToProvider(publicClient)
}
```
</Tab>
</Tabs>

### Usage

Now you can use the `useEthersProvider` Hook in your components:

```ts filename="src/example.ts"
import { getEthersProvider } from './ethers'

function example() {
const provider = getEthersProvider()
...
}
```

## Wallet Client → Signer

### Reference Implementation

Copy the following reference implementation into a file of your choice:

<Tabs items={['ethers.js v5', 'ethers.js v6']}>
<Tab>
```ts filename="src/ethers.ts"
import { type WalletClient, getWalletClient } from '@wagmi/core'
import { providers } from 'ethers'

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
}

/** Action to convert a viem Wallet Client to an ethers.js Signer. */
export async function getEthersSigner({ chainId }: { chainId?: number } = {}) {
const walletClient = await getWalletClient({ chainId })
if (!walletClient) return undefined
return walletClientToSigner(walletClient)
}
```
</Tab>
<Tab>
```ts filename="src/ethers.ts"
import { type WalletClient, useWalletClient } from 'wagmi'
import { BrowserProvider, JsonRpcSigner } from 'ethers'

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 BrowserProvider(transport, network)
const signer = new JsonRpcSigner(provider, account.address)
return signer
}

/** Action to convert a viem Wallet Client to an ethers.js Signer. */
export async function getEthersSigner({ chainId }: { chainId?: number } = {}) {
const walletClient = await getWalletClient({ chainId })
if (!walletClient) return undefined
return walletClientToSigner(walletClient)
}
```
</Tab>
</Tabs>

### Usage

Now you can use the `useEthersSigner` Hook in your components:

```ts filename="src/example.ts"
import { getEthersSigner } from './ethers'

function example() {
const signer = getEthersSigner()
...
}
```
3 changes: 2 additions & 1 deletion docs/pages/react/_meta.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"comparison": "Library Comparison",
"migration-guide": "Migration Guide",
"typescript": "TypeScript",
"config": "Config",
"config": "createConfig",
"WagmiConfig": "WagmiConfig",
"chains": "Chains",
"providers": "Providers",
Expand All @@ -12,6 +12,7 @@
"prepare-hooks": "Prepare Hooks",
"constants": "Constants",
"actions": "Actions",
"ethers-adapters": "Ethers.js Adapters",
"module-types": "Module Types",
"faq": "FAQ"
}
2 changes: 1 addition & 1 deletion docs/pages/react/_meta.zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"title": "TypeScript"
},
"config": {
"title": "Config",
"title": "createConfig",
"display": "hidden"
},
"WagmiConfig": {
Expand Down
176 changes: 176 additions & 0 deletions docs/pages/react/ethers-adapters.en-US.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
title: 'Ethers.js Adapters'
description: 'Adapters for ethers.js'
---

import { Tabs, Tab } from 'nextra-theme-docs'

# Ethers.js Adapters

It is recommended for projects to migrate to [viem](https://viem.sh) when using wagmi, but there are some cases where you might still need to use [ethers.js](https://ethers.org/) in your project:

- You may want to **incrementally migrate** ethers.js usage to viem
- Some **third-party libraries & SDKs** may only support ethers.js

We have provided reference implementations for viem → ethers.js adapters that you can copy + paste in your project.

## Public Client → Provider

### Reference Implementation

Copy the following reference implementation into a file of your choice:

<Tabs items={['ethers.js v5', 'ethers.js v6']}>
<Tab>
```ts filename="src/ethers.ts"
import * as React from 'react'
import { type PublicClient, usePublicClient } from 'wagmi'
import { providers } from 'ethers'
import { type HttpTransport } from 'viem'

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)
}

/** Hook to convert a viem Public Client to an ethers.js Provider. */
export function useEthersProvider({ chainId }: { chainId?: number } = {}) {
const publicClient = usePublicClient({ chainId })
return React.useMemo(() => publicClientToProvider(publicClient), [publicClient])
}
```
</Tab>
<Tab>
```ts filename="src/ethers.ts"
import * as React from 'react'
import { type PublicClient, usePublicClient } from 'wagmi'
import { FallbackProvider, JsonRpcProvider } from 'ethers'
import { type HttpTransport } from 'viem'

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') {
const providers = (transport.transports as ReturnType<HttpTransport>[]).map(
({ value }) => new JsonRpcProvider(value?.url, network),
)
if (providers.length === 1) return providers[0]
return new FallbackProvider(providers)
}
return new JsonRpcProvider(transport.url, network)
}

/** Hook to convert a viem Public Client to an ethers.js Provider. */
export function useEthersProvider({ chainId }: { chainId?: number } = {}) {
const publicClient = usePublicClient({ chainId })
return React.useMemo(() => publicClientToProvider(publicClient), [publicClient])
}
```
</Tab>
</Tabs>

### Usage

Now you can use the `useEthersProvider` Hook in your components:

```ts filename="src/Example.ts"
import { useEthersProvider } from './ethers'

function Example() {
const provider = useEthersProvider()
...
}
```

## Wallet Client → Signer

### Reference Implementation

Copy the following reference implementation into a file of your choice:

<Tabs items={['ethers.js v5', 'ethers.js v6']}>
<Tab>
```ts filename="src/ethers.ts"
import * as React from 'react'
import { type WalletClient, useWalletClient } from 'wagmi'
import { providers } from 'ethers'

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
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
export function useEthersSigner({ chainId }: { chainId?: number } = {}) {
const { data: walletClient } = useWalletClient({ chainId })
return React.useMemo(
() => (walletClient ? walletClientToSigner(walletClient) : undefined),
[walletClient],
)
}
```
</Tab>
<Tab>
```ts filename="src/ethers.ts"
import * as React from 'react'
import { type WalletClient, useWalletClient } from 'wagmi'
import { BrowserProvider, JsonRpcSigner } from 'ethers'

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 BrowserProvider(transport, network)
const signer = new JsonRpcSigner(provider, account.address)
return signer
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
export function useEthersSigner({ chainId }: { chainId?: number } = {}) {
const { data: walletClient } = useWalletClient({ chainId })
return React.useMemo(
() => (walletClient ? walletClientToSigner(walletClient) : undefined),
[walletClient],
)
}
```
</Tab>
</Tabs>

### Usage

Now you can use the `useEthersSigner` Hook in your components:

```ts filename="src/Example.ts"
import { useEthersSigner } from './ethers'

function Example() {
const signer = useEthersSigner()
...
}
```

1 comment on commit 912adb2

@vercel
Copy link

@vercel vercel bot commented on 912adb2 Jun 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.