-
Notifications
You must be signed in to change notification settings - Fork 204
feat: add createAlchemyConfig and AlchemyProvider #2125
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
base: moldy/v5-base
Are you sure you want to change the base?
Changes from all commits
2a8be0c
482d5ff
750fd0e
51c0f74
1de77b7
9ea5c19
89713d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| --- | ||
| # This file is autogenerated | ||
| title: AlchemyProvider | ||
| description: Overview of the AlchemyProvider method | ||
| slug: wallets/reference/alchemy/react/components/AlchemyProvider | ||
| --- | ||
|
|
||
| AlchemyProvider component that wraps the necessary providers for Alchemy functionality | ||
|
|
||
| This component: | ||
|
|
||
| - Wraps WagmiProvider with the wagmi config from createAlchemyConfig | ||
| - Will wrap additional providers in the future (Solana, UI, etc.) | ||
|
|
||
| ## Import | ||
|
|
||
| ```ts | ||
| import { AlchemyProvider } from "@alchemy/react"; | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```tsx | ||
| import { AlchemyProvider, createAlchemyConfig } from "@alchemy/react"; | ||
| import { arbitrumSepolia, sepolia } from "wagmi/chains"; | ||
|
|
||
| const config = createAlchemyConfig({ | ||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY!, | ||
| chains: [arbitrumSepolia, sepolia], | ||
| }); | ||
|
|
||
| export function App({ children }) { | ||
| return <AlchemyProvider config={config}>{children}</AlchemyProvider>; | ||
| } | ||
| ``` | ||
|
|
||
| ## Parameters | ||
|
|
||
| ### props | ||
|
|
||
| `AlchemyProviderProps` | ||
|
|
||
| - The props for the AlchemyProvider component | ||
|
|
||
| ### props.config | ||
|
|
||
| `AlchemyReactConfig` | ||
|
|
||
| - The Alchemy configuration object created by createAlchemyConfig | ||
|
|
||
| ### props.children | ||
|
|
||
| `ReactNode` | ||
|
|
||
| - Child components to render | ||
|
|
||
| ## Returns | ||
|
|
||
| `JSX.Element` | ||
| The wrapped React components with Alchemy providers | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| --- | ||
| # This file is autogenerated | ||
| title: createAlchemyConfig | ||
| description: Overview of the createAlchemyConfig method | ||
|
||
| slug: wallets/reference/alchemy/react/functions/createAlchemyConfig | ||
| --- | ||
|
|
||
| Creates a simplified Alchemy configuration for React applications | ||
|
|
||
| This function removes the boilerplate of setting up wagmi with Alchemy by: | ||
|
|
||
| - Automatically configuring Alchemy transport for each chain | ||
| - Automatically adding Alchemy auth connector | ||
| - Providing sensible defaults | ||
| - Offering escape hatches for advanced customization | ||
|
|
||
| ## Import | ||
|
|
||
| ```ts | ||
| import { createAlchemyConfig } from "@alchemy/react"; | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```tsx | ||
| import { createAlchemyConfig } from "@alchemy/react"; | ||
| import { arbitrumSepolia, sepolia } from "wagmi/chains"; | ||
|
|
||
| const config = createAlchemyConfig({ | ||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY!, | ||
| chains: [arbitrumSepolia, sepolia], | ||
| }); | ||
|
|
||
| // Use with AlchemyProvider or WagmiProvider | ||
| <AlchemyProvider config={config}>{children}</AlchemyProvider>; | ||
| ``` | ||
|
|
||
| ## Parameters | ||
|
|
||
| ### options | ||
|
|
||
| `CreateAlchemyConfigOptions` | ||
|
|
||
| - Configuration options for the Alchemy config | ||
|
|
||
| ## Returns | ||
|
|
||
| `AlchemyReactConfig` | ||
| AlchemyReactConfig object containing the wagmi config | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,7 @@ | ||
| import { createConfig } from "wagmi"; | ||
| import { arbitrumSepolia, sepolia } from "wagmi/chains"; | ||
| import { alchemyAuth } from "@alchemy/connectors-web"; | ||
| import { alchemyTransport } from "@alchemy/common"; | ||
| import { createAlchemyConfig } from "@alchemy/react"; | ||
|
|
||
| export const config = createConfig({ | ||
| connectors: [ | ||
| alchemyAuth({ | ||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY, | ||
| }), | ||
| ], | ||
| export const config = createAlchemyConfig({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. beautiful |
||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY, | ||
| chains: [arbitrumSepolia, sepolia], | ||
| transports: { | ||
| [arbitrumSepolia.id]: alchemyTransport({ | ||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY, | ||
| }), | ||
| [sepolia.id]: alchemyTransport({ | ||
| apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY, | ||
| }), | ||
| }, | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,16 @@ | ||
| "use client"; | ||
|
|
||
| import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; | ||
| import { WagmiProvider } from "wagmi"; | ||
| import { AlchemyProvider } from "@alchemy/react"; | ||
| import { config } from "./config.ts"; | ||
| import { ReactNode } from "react"; | ||
|
|
||
| const queryClient = new QueryClient(); | ||
|
|
||
| export const Providers = ({ children }: { children: ReactNode }) => { | ||
| return ( | ||
| <WagmiProvider config={config}> | ||
| <AlchemyProvider config={config}> | ||
| <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> | ||
| </WagmiProvider> | ||
| </AlchemyProvider> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| "use client"; | ||
|
|
||
| import { type ReactNode } from "react"; | ||
| import { WagmiProvider } from "wagmi"; | ||
| import type { AlchemyReactConfig } from "./createAlchemyConfig.js"; | ||
|
|
||
| /** | ||
| * Props for the AlchemyProvider component | ||
| */ | ||
| export type AlchemyProviderProps = { | ||
| /** The Alchemy configuration object created by createAlchemyConfig */ | ||
| config: AlchemyReactConfig; | ||
| /** Child components to render */ | ||
| children: ReactNode; | ||
| }; | ||
|
|
||
| /** | ||
| * AlchemyProvider component that wraps the necessary providers for Alchemy functionality | ||
| * | ||
| * This component: | ||
| * - Wraps WagmiProvider with the wagmi config from createAlchemyConfig | ||
| * - Will wrap additional providers in the future (Solana, UI, etc.) | ||
| * | ||
| * @param {AlchemyProviderProps} props - The props for the AlchemyProvider component | ||
| * @param {AlchemyReactConfig} props.config - The Alchemy configuration object created by createAlchemyConfig | ||
| * @param {ReactNode} props.children - Child components to render | ||
| * @returns {JSX.Element} The wrapped React components with Alchemy providers | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * import { AlchemyProvider, createAlchemyConfig } from "@alchemy/react"; | ||
| * import { arbitrumSepolia, sepolia } from "wagmi/chains"; | ||
| * | ||
| * const config = createAlchemyConfig({ | ||
| * apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY!, | ||
| * chains: [arbitrumSepolia, sepolia], | ||
| * }); | ||
| * | ||
| * export function App({ children }) { | ||
| * return ( | ||
| * <AlchemyProvider config={config}> | ||
| * {children} | ||
| * </AlchemyProvider> | ||
| * ); | ||
| * } | ||
| * ``` | ||
| */ | ||
| export function AlchemyProvider({ config, children }: AlchemyProviderProps) { | ||
| return ( | ||
| <WagmiProvider config={config.wagmi}> | ||
| {children} | ||
| {/* Future: Additional providers will be added here */} | ||
| {/* e.g., <AlchemySolanaProvider config={config.solana}> */} | ||
| {/* e.g., <AlchemyUIProvider config={config.ui}> */} | ||
| </WagmiProvider> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,135 @@ | ||||||
| import { alchemyTransport } from "@alchemy/common"; | ||||||
| import { alchemyAuth } from "@alchemy/connectors-web"; | ||||||
| import { createConfig, type CreateConfigParameters, type Config } from "wagmi"; | ||||||
| import type { Chain } from "viem"; | ||||||
|
|
||||||
| /** | ||||||
| * Configuration options for creating an Alchemy config | ||||||
| */ | ||||||
| export type CreateAlchemyConfigOptions = { | ||||||
| /** | ||||||
| * Alchemy API key for authentication and transport | ||||||
| */ | ||||||
| apiKey?: string; | ||||||
|
|
||||||
| /** | ||||||
| * Alchemy JWT for authentication and transport | ||||||
| */ | ||||||
| jwt?: string; | ||||||
|
|
||||||
| /** | ||||||
| * Custom RPC URL for transport | ||||||
| */ | ||||||
| url?: string; | ||||||
|
|
||||||
| /** | ||||||
| * List of EVM chains to support | ||||||
| */ | ||||||
| chains: [Chain, ...Chain[]]; | ||||||
|
|
||||||
| /** | ||||||
| * Policy IDs for gas sponsorship (optional) | ||||||
| */ | ||||||
| policyIds?: string[]; | ||||||
|
|
||||||
| /** | ||||||
| * Enable server-side rendering support (optional) | ||||||
| */ | ||||||
| ssr?: boolean; | ||||||
| }; | ||||||
|
|
||||||
| /** | ||||||
| * Return type for createAlchemyConfig | ||||||
| */ | ||||||
| export type AlchemyReactConfig = { | ||||||
| /** Wagmi config for use with WagmiProvider */ | ||||||
| wagmi: Config; | ||||||
|
|
||||||
| // Future extensions (not implemented in M2): | ||||||
| // solana?: AlchemySolanaConfig; | ||||||
| // ui?: AlchemyUIConfig; | ||||||
| }; | ||||||
|
|
||||||
| /** | ||||||
| * Creates a simplified Alchemy configuration for React applications | ||||||
| * | ||||||
| * This function removes the boilerplate of setting up wagmi with Alchemy by: | ||||||
| * - Automatically configuring Alchemy transport for each chain | ||||||
| * - Automatically adding Alchemy auth connector | ||||||
| * - Providing sensible defaults | ||||||
| * - Offering escape hatches for advanced customization | ||||||
| * | ||||||
| * @example | ||||||
| * ```tsx | ||||||
| * import { createAlchemyConfig } from "@alchemy/react"; | ||||||
| * import { arbitrumSepolia, sepolia } from "wagmi/chains"; | ||||||
| * | ||||||
| * const config = createAlchemyConfig({ | ||||||
| * apiKey: process.env.NEXT_PUBLIC_ALCHEMY_API_KEY!, | ||||||
| * chains: [arbitrumSepolia, sepolia], | ||||||
| * }); | ||||||
| * | ||||||
| * // Use with AlchemyProvider or WagmiProvider | ||||||
| * <AlchemyProvider config={config}> | ||||||
| * {children} | ||||||
| * </AlchemyProvider> | ||||||
| * ``` | ||||||
| * | ||||||
| * @param {CreateAlchemyConfigOptions} options - Configuration options for the Alchemy config | ||||||
| * @returns {AlchemyReactConfig} AlchemyReactConfig object containing the wagmi config | ||||||
| */ | ||||||
| export function createAlchemyConfig( | ||||||
| options: CreateAlchemyConfigOptions, | ||||||
| ): AlchemyReactConfig { | ||||||
| const { | ||||||
| apiKey, | ||||||
| jwt, | ||||||
| url, | ||||||
| chains, | ||||||
| // policyIds, // TODO: add when smart wallet becomes default | ||||||
| ssr = false, | ||||||
| } = options; | ||||||
|
|
||||||
| if (!chains?.length) { | ||||||
|
||||||
| if (!chains?.length) { | |
| if (!chains.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up not implementing the wagmiOverrides option in this PR. I wanted to get some opinions on it. I struggled getting the types to work for some reason, I kept getting a type error when doing a shallow copy into the params.
It got me thinking, I wonder if we should just try to expose options that we see fit (rather than a full wagmiOverrides option. And if anyone needs a bunch of wagmi overrides, we just recommend they build the wagmi config themselves.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,16 @@ | ||
| // Hooks | ||
| export type * from "./hooks/useSendEmailOtp.js"; | ||
| export { useSendEmailOtp } from "./hooks/useSendEmailOtp.js"; | ||
| export type * from "./hooks/useSubmitOtpCode.js"; | ||
| export { useSubmitOtpCode } from "./hooks/useSubmitOtpCode.js"; | ||
|
|
||
| // Configuration | ||
| export type { | ||
| CreateAlchemyConfigOptions, | ||
| AlchemyReactConfig, | ||
| } from "./createAlchemyConfig.js"; | ||
| export { createAlchemyConfig } from "./createAlchemyConfig.js"; | ||
|
|
||
| // Providers | ||
| export type { AlchemyProviderProps } from "./AlchemyProvider.js"; | ||
| export { AlchemyProvider } from "./AlchemyProvider.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description refers to
AlchemyProvideras a 'method' but it's actually a React component. Should be 'Overview of the AlchemyProvider component' to be technically accurate.