Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brian doyle/add connecting to chain mod #132

Merged
merged 8 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
---
title: Overview of Providers
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved
description: Configure several providers and use them to connect to the blockchain.
hide_table_of_contents: false
---

[Rainbowkit] is a popular library that works with [wagmi] to make it easy to connect, disconnect, and change between multiple wallets. It's batteries-included out of the box, and allows for a great deal of customization of the list of wallets and connect/disconnect button.

---

## Prerequisites

Before this lesson, you should:

- Be familiar with modern, frontend web development
- Possess a general understanding of the EVM and smart contracts
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved
- Ideally, understand how to build a frontend with [Next.js]

---

## Objectives

By the end of this lesson you should be able to:

- Set up a provider in wagmi and use it to connect a wallet
- Protect API keys that will be exposed to the front end

---

## Connecting to the Blockchain

We'll be using Rainbowkit's [quick start] to scaffold a new project for this guide.

:::info

The script doesn't allow you to use `.` to create a project in the root of the folder you run it from, so you'll want to run it from your `src` directory, or wherever you keep your project folders.

It will create a folder with the project name you give, and create the files inside.

:::

Open up a terminal and run:

```bash
yarn create @rainbow-me/rainbowkit
```

Give your project a name, and wait for the script to build it. It will take a minute or two.

### Scaffolded App

Open your new project in the editor of your choice, and open `pages/_app.tsx`. Here, you'll find a familiar Next.js app wrapped in [context providers] for Rainbowkit and wagmi.

```typescript
function MyApp({ Component, pageProps }: AppProps) {
return (
<wagmiConfig config={wagmiConfig}>
<RainbowKitProvider chains={chains}>
<Component {...pageProps} />
</RainbowKitProvider>
</wagmiConfig>
);
}
```

Note that these providers are using React's context feature to pass the blockchain providers and configuration into your app. It can be confusing to have the word _provider_ meaning two different things in the same file, or even the same line of code!

briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved
Before you can do anything else, you need to obtain a _WalletConnect_ `projectId`.

Open up the [WalletConnect] homepage, and create an account and/or sign in using the method of your choice.

Click the `Create` button in the upper right of the `Projects` tab.

![Create Button](../../assets/images/connecting-to-the-blockchain/wallet-connect-create-button.png)

Enter a name for your project, select the `App` option, and click `Create`.

![Project Information](../../assets/images/connecting-to-the-blockchain/add-project-information.png)

Copy the _Project ID_ from the project information page, and paste it in as the `projectId` in `getDefaultWallets`.

```typescript
const { connectors } = getDefaultWallets({
appName: 'RainbowKit App',
projectId: 'YOUR_PROJECT_ID',
chains,
});
```

:::caution

Remember, anything you put on the frontend is public! That includes this id, even if you use environment variables to better manage this type of data. Next.js reminds you of the risk, by requiring you to prepend `NEXT_PUBLIC_` to any environment variables that can be read by the browser.

Before you deploy, make sure you configure the rest of the items in the control panel to ensure only your site can use this id.

:::

### Public Provider

By default, the setup script will configure your app to use the `publicProvider()`, and connect to a number of popular chains. To simply matters, remove all but `mainnnet`, `optimism`, and `base`.

```typescript
const { chains, publicClient, webSocketPublicClient } = configureChains(
[mainnet, optimism, base],
[publicProvider()],
);
```

Open the terminal and start the app with:

```bash
yarn run dev
```

Click the `Connect Wallet` button, select your wallet from the modal, approve the connection, and you should see your network, token balance, and address or ENS name at the top of the screen. Select your wallet from the modal.

![Rainbowkit modal](../../assets/images/connecting-to-the-blockchain/rainbowkit-modal.png)

You've connected with the Public Provider!

![Connected](../../assets/images/connecting-to-the-blockchain/connected.png)

### QuickNode

Notice that the [`configureChains`] function takes in an array of providers. It will attempt to use each one in the order provided, falling back to the next in the list in order if something goes wrong. You can use this for redundancy, or to smoothly handle scenarios where your app needs to connect with a chain that isn't supported by your preferred provider.

Let's add [QuickNode] to the list. It isn't [included in the library] by default, so you'll need to add it using the generic [JSON RPC provider] import.

```typescript
import { jsonRpcProvider } from 'wagmi/providers/jsonRpc';
```

Unlike the linked example indicates, you do **not** need to add an import `chain` from `'wagmi'` (Their example appears out of date at the time of writing).
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

You do need an RPC URL, so open up [QuickNode]'s site and sign up for an account if you need to. The free tier will be adequate for now, you may need to scroll down to see it. Once you're in, click `Endpoints` on the left side, then click `+ Create Endpoint`.

On the next screen, you'll be asked to select a chain. Each endpoint only works for one. Select `Base`, click `Continue`.

![Select Chain](../../assets/images/connecting-to-the-blockchain/quicknode-select-chain.png)

For now, pick `Base Mainnet`, but you'll probably want to delete this endpoint and create a new one for Goerli or Sepolia when you start building. The free tier only allows you to have one at a time.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use testnet now for this lesson?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No strong reason, other than it's already imported, and IMO neat to connect to the "real" thing.


If you haven't already picked a tier, you'll be asked to do so, then you'll be taken to the endpoints page, which will display your endpoints for HTTP and WSS.

:::caution

As with your WalletConnect Id, these endpoints will be visible on the frontend. Be sure to configure the allowlist!

:::

Use these endpoints to add a `jsonRpcProvider` to your array of providers:

```typescript
const { chains, publicClient, webSocketPublicClient } = configureChains(
[mainnet, optimism, base],
[
jsonRpcProvider({
rpc: () => ({
http: 'https://endpoint-name.quiknode.pro/<key>/',
webSocket: 'wss://endpoint-name.quiknode.pro/<key>/',
}),
}),
publicProvider(),
],
);
```

Now, the app will use your Quicknode endpoint for the Base network, and fall back to the public provider for others.

To test this out, comment out `publicProvider()`, and switch networks a few times. Unfortunately, wagmi won't generate an error when you try to connect to a network unsupported by the provider, but you will notice that the wallet balance is only shown correctly for Base, and no longer updates when you switch to other networks.

### Blockdaemon

[Blockdaemon] also needs to be set up as a JSON RPC provider. Log in, [or create an account], navigate to the `API Suite` tab on the left, and click `Create API Key`.

![Create api key](../../assets/images/connecting-to-the-blockchain/blockdaemon-create-key.png)

TODO PENDING MORE INFORMATION!!!

### Alchemy

[Alchemy] is [baked into wagmi], but you still need an account and a key. Create an account and/or sign in, navigate to the `Apps` section in the left sidebar, and click `Create new app`.

![Alchemy new app](../../assets/images/connecting-to-the-blockchain/alchemy-new-app.png)

Select Base Mainnet, and give your app a name.

:::caution

Once again, remember to configure the [allowlist] when you publish your app, as you'll be exposing your key to the world!

:::

On the dashboard for your new app, click the `API key` button, and copy the key to the clipboard.

Import `alchemyProvider`, then add it to your list of providers:

```typescript
import { alchemyProvider } from 'wagmi/providers/alchemy';

const { chains, publicClient, webSocketPublicClient } = configureChains(
[mainnet, optimism, base],
[
// jsonRPC Providers
alchemyProvider({ apiKey: 'yourAlchemyApiKey' }),
publicProvider(),
],
);
```

As before, you can confirm the Alchemy Provider is working by commenting out the others and changing the network.

---

## Conclusion

In this guide, you've learned how to connect your app to the blockchain using several different providers, including the public provider(s). You've also learned that you need to use allowlists to protect your plan usage, because you'll be exposing your keys to the world. Finally, you've learned how wagmi will attempt to use each provider in order, falling back to the next in the list if one fails.

---

[Next.js]: https://nextjs.org
[wagmi]: https://wagmi.sh
[Rainbowkit]: https://www.rainbowkit.com
[quick start]: https://www.rainbowkit.com/docs/installation
[context providers]: https://react.dev/learn/passing-data-deeply-with-context
[WalletConnect]: https://cloud.walletconnect.com/
[`configureChains`]: https://wagmi.sh/react/providers/configuring-chains
[included in the library]: https://github.com/wagmi-dev/wagmi/tree/main/packages/core/src/providers
[JSON RPC provider]: https://wagmi.sh/react/providers/jsonRpc
[Alchemy]: https://www.alchemy.com/
[Blockdaemon]: https://www.blockdaemon.com/
[QuickNode]: https://www.quicknode.com/
[allowlist]: https://docs.alchemy.com/docs/how-to-add-allowlists-to-your-apps-for-enhanced-security
[baked into wagmi]: https://wagmi.sh/react/providers/alchemy
[create an account]: https://app.blockdaemon.com/signin/register
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: Overview of Providers
description: Learn what providers are and why you need one.
hide_table_of_contents: false
---

Onchain apps need frontends, sometimes called dApps, to enable your users to interact with your smart contracts. A _provider_ makes the connection from frontend to blockchain, and is used to read data and send transactions.

---

## Prerequisites

Before this lesson, you should:
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

- Be familiar with modern, frontend web development
- Possess a general understanding of the EVM and smart contracts
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved
- Ideally, understand how to build a frontend with [Next.js]

---

## Objectives

By the end of this lesson you should be able to:
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

- Compare and contrast public providers vs. vendor providers vs. wallet providers
- Select the appropriate provider for several use cases

---

## Types of Providers

In blockchain development, the term _provider_ describes a company or service that provides an API enabling access to the blockchain as a service. This is distinct from the provider in the the React Context API or Redux Provider, though you will also wrap your app with `wagmiConfig` in a similar manner.
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

These services enable interacting with smart contracts without the developer needing to run and maintain their own blockchain node. Running a node is expensive, complicated, and challenging. In most cases, you'll want to start out with a provider. Once you start to get traction, you can evaluate the need to run your own node, or switch to a more advanced architecture solution, such as utilizing [Subgraph].
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

Figuring out which type of provider to use can be a little confusing at first. As with everything blockchain, the landscape changes rapidly and search results often return out-of-date information.

:::info

New onchain devs sometimes get the impression that there are free options for connecting their apps to the blockchain. Unfortunately, this is not really true. Blockchain data is still 1's and 0's, fetched by computation and served to the internet via servers.

It costs money to run these and you will eventually need to pay for the service.

:::

You'll encounter providers divided into three general categories: Public Providers, Wallet Providers, and Vendor Providers

### Public Providers

Many tutorials and guides, as well getting started guides for libraries such as [wagmi], will use a _Public Provider_ as the default to get you up and running. Public means that they're open, permissionless, and free, so the guides will also usually warn you that you need to add another provider if you don't want to run into rate limiting. Listen to these warnings! The rate-limits of public providers are severe and you'll start getting limited very quickly.
Copy link
Contributor

@taycaldwell taycaldwell Nov 17, 2023

Choose a reason for hiding this comment

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

A lot of this guide makes mention of the wagmi team's tooling wagmi, viem. Feels like we're specifically promoting them, although the reader may not be familiar with those offerings.

I know this is an ongoing debate - but is it possible to reword the content in a way that doesn't feel bias towards specific third party library / tooling, since this guide isn't reliant or specific to those libraries? (other page is wagmi/rainbowkit specific, but this one doesn't seem like it has to be).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we can with this one. It's going to be wrapped as a single guide for connecting using them, and will eventually also be embedded in the frontend series for Basecamp, which also uses Rainbowkit/Wagmi/Viem. The references are foreshadowing tasks that they'll be doing in the step by step part.

Were it a blog post, we'd definitely need to neutralize it.


In wagmi, the `publicClient` is just a wrapper setting up a [JSON RPC] provider using the `chain` and `rpcUrls` listed in Viem's directory of chain information. For example, you can view the [data for Base Goerli here].

Most chains will list this information in their docs as well. For example, on the network information pages for [Base] and [Optimism]. If you wanted, you could manually set up a `jsonRpcProvider` in wagmi using this information.

### Wallet Providers

Many wallets, including Coinbase and Metamask, inject an Ethereum provider into the browser, as defined in [EIP-1193]. The injected provider is accessible via `window.ethereum`.
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

Under the hood, these are also just JSON RPC providers. Similar to public providers, they are rate-limited.

Older tutorials for early libraries tended to suggest using this method for getting started, so you'll probably encounter references to it. However, it's fallen out of favor and you'll want to use the public provider for your initial connection experiments.

### Vendor Providers

A growing number of vendors provide access to blockchain nodes as a service. Visiting the landing pages for [Quicknode] (formerly Quiknode), [Blockdaemon], or [Alchemy] can be a little confusing. Each of these vendors provides a wide variety of services, SDKs, and information.
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved

Luckily, you can skip most of this if you're just trying to get your frontend connected to you smart contracts, because most of it is handled by wagmi/Viem. You'll just need to sign up for an account and get an endpoint, or a key, and configure your app to connect to the provider(s) you choose.

It is worth digging in to get a better understanding of how these providers charge you for their services. The table below summarizes some of the more important API methods, and how you are charged for them by each of the above providers.

Note that the information below may change, and varies by network. Each provider also has different incentives, discounts, and fees for each level of product. They also have different allowances for calls per second, protocols, and number of endpoints. Please check the source to confirm!

| | [Alchemy Costs] | [Blockdaemon Costs] | [Quicknode Costs] |
| --------------- | ---------------- | ------------------- | ----------------- |
briandoyle81CB marked this conversation as resolved.
Show resolved Hide resolved
| Free Tier / Mo. | 3M compute units | 3M compute units | 50M credits |
| Mid Tier / Mo. | 1.5B CUs @ $199 | 30M CUs @ $199 | 3B credits @ $299 |
| eth_blocknumber | 10 | 1 | 20 |
| eth_call | 26 | 10 | 20 |
| eth_getlogs | 75 | 50 | 20 |
| eth_getbalance | 19 | 5 | 20 |

To give you an idea of usage amounts, a single wagmi `useContractRead` hook set to `watch` for changes on a single `view` will call `eth_blocknumber` and `eth_call` one time each, every 4 seconds.

---

## Conclusion

In this article, you've learned how Providers supply blockchain connection as a service, eliminating the need for developers to run and maintain their own nodes. You've also seen three options for vendors and explored the similarities and differences in how they price their services. Finally, you've learned that a public provider will let you do your initial explorations in connecting to your smart contracts, but they are severely rate-limited.

---

[Next.js]: https://nextjs.org/
[Subgraph]: https://thegraph.com/docs/en/developing/creating-a-subgraph/
[wagmi]: https://wagmi.sh/react/getting-started#configure-chains
[data for Base Goerli here]: https://github.com/wagmi-dev/viem/blob/main/src/chains/definitions/baseGoerli.ts
[Base]: https://docs.base.org/network-information
[Optimism]: https://community.optimism.io/docs/useful-tools/networks/
[EIP-1193]: https://eips.ethereum.org/EIPS/eip-1193
[Alchemy]: https://www.alchemy.com/
[Blockdaemon]: https://www.blockdaemon.com/
[Quicknode]: https://www.quicknode.com/
[Alchemy Costs]: https://docs.alchemy.com/reference/compute-unit-costs
[Blockdaemon Costs]: https://docs.blockdaemon.com/reference/ethereum-compute-units
[Quicknode Costs]: https://www.quicknode.com/api-credits/base