diff --git a/.env.local.example b/.env.local.example index 7683965..7aaf143 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,7 +1,7 @@ # duplicate this file and rename to .env.local and fill in all items # Provider URI (https://... from Alchemy, Quicknode, Infura, etc) -NEXT_PUBLIC_PROVIDER_URI_SEPOLIA= +NEXT_PUBLIC_PROVIDER_URI_11155111= # Get your project ID from WalletConnect Cloud https://cloud.walletconnect.com/ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID= diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b013f85..d53f1ef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ on: pull_request: env: - NEXT_PUBLIC_PROVIDER_URI_SEPOLIA: ${{ secrets.NEXT_PUBLIC_PROVIDER_URI_SEPOLIA }} + NEXT_PUBLIC_PROVIDER_URI_11155111: ${{ secrets.NEXT_PUBLIC_PROVIDER_URI_11155111 }} NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID }} jobs: diff --git a/README.md b/README.md index d55f203..ee9c616 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This Axiom Next.js 14 Quickstart provides a barebones framework through which yo 1. Copy `.env.local.example` as a new file named `.env.local` 2. Fill in the values in `.env.local` with your own values - a. `NEXT_PUBLIC_PROVIDER_URI_SEPOLIA` is your provider API key; you'll need to sign up for an [Alchemy](https://www.alchemy.com/) or [QuickNode](https://www.quicknode.com) account + a. `NEXT_PUBLIC_PROVIDER_URI_[CHAIN_ID]` is your provider API key (`[CHAIN_ID]` is the chain ID number of the network you are using); you'll need to sign up for an [Alchemy](https://www.alchemy.com/) or [QuickNode](https://www.quicknode.com) account b. `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` is your WalletConnect project ID; you'll need to sign up for a [WalletConnect](https://walletconnect.com/) account 3. Run `npm install` (or `yarn`/`pnpm`) to install dependencies 4. Run `npm run dev` to start the local development server diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b3554b8..1943201 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,3 +1,55 @@ +import { Chain } from 'viem' +import { base, baseSepolia, mainnet, sepolia } from 'viem/chains' + +// Unfortunately, dynamic environment variables are not supported in Next.js +// so we can't just do process.env[`NEXT_PUBLIC_PROVIDER_URI_${CHAIN_ID}`]. +// We'll need to do something like this to get the provider URI. +export const getProviderClientSide = (chainId: string): string => { + switch (chainId) { + case "1": + return process.env.NEXT_PUBLIC_PROVIDER_URI_1 as string; + case "11155111": + return process.env.NEXT_PUBLIC_PROVIDER_URI_11155111 as string; + case "8453": + return process.env.NEXT_PUBLIC_PROVIDER_URI_8453 as string; + case "84532": + return process.env.NEXT_PUBLIC_PROVIDER_URI_84532 as string; + default: + throw new Error(`Unsupported chainId: ${chainId}`) + } +} + +export const chainIdToViemChain = (chainId: string): Chain => { + switch (chainId) { + case "1": + return mainnet; + case "11155111": + return sepolia; + case "8453": + return base; + case "84532": + return baseSepolia; + default: + throw new Error(`Unsupported chainId: ${chainId}`) + } +}; + +export const chainIdToExplorerBaseUrl = (chainId: string): string => { + switch (chainId) { + case "1": + return "https://explorer.axiom.xyz/v2/mainnet"; + case "11155111": + return "https://explorer.axiom.xyz/v2/sepolia"; + case "8453": + return "https://explorer.axiom.xyz/v2/base"; + case "84532": + return "https://explorer.axiom.xyz/v2/base-sepolia"; + default: + throw new Error(`Unsupported chainId: ${chainId}`) + } +} + + const truncateRegex = /^(0x[a-zA-Z0-9]{4})[a-zA-Z0-9]+([a-zA-Z0-9]{4})$/; export const shortenAddress = (address: string) => { diff --git a/src/lib/viemClient.ts b/src/lib/viemClient.ts index f83303c..b6b0dd7 100644 --- a/src/lib/viemClient.ts +++ b/src/lib/viemClient.ts @@ -1,7 +1,8 @@ import { createPublicClient, http } from 'viem' -import { sepolia } from 'viem/chains' +import { CHAIN_ID, WebappSettings } from './webappSettings'; +import { chainIdToViemChain } from './utils'; export const publicClient = createPublicClient({ - chain: sepolia, - transport: http() -}) \ No newline at end of file + chain: chainIdToViemChain(CHAIN_ID), + transport: http(WebappSettings.provider) +}); diff --git a/src/lib/wagmiConfig.ts b/src/lib/wagmiConfig.ts index 2f87f7a..53e4498 100644 --- a/src/lib/wagmiConfig.ts +++ b/src/lib/wagmiConfig.ts @@ -1,9 +1,8 @@ import { http, createConfig } from 'wagmi' -import { sepolia } from 'wagmi/chains' import { injected, walletConnect } from 'wagmi/connectors' import { createWeb3Modal } from '@web3modal/wagmi/react'; - -const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID as string; +import { CHAIN_ID, PROJECT_ID } from './webappSettings'; +import { chainIdToViemChain } from './utils'; const metadata = { name: 'Axiom Next.js Scaffold', @@ -13,17 +12,17 @@ const metadata = { } export const wagmiConfig = createConfig({ - chains: [sepolia], + chains: [chainIdToViemChain(CHAIN_ID)], transports: { - [sepolia.id]: http(process.env.NEXT_PUBLIC_PROVIDER_URI_SEPOLIA as string) + [Number(CHAIN_ID)]: http(process.env[`NEXT_PUBLIC_PROVIDER_URI_${CHAIN_ID}`] as string) }, connectors: [ - walletConnect({ projectId, metadata, showQrModal: false }), + walletConnect({ projectId: PROJECT_ID, metadata, showQrModal: false }), injected({ shimDisconnect: true }), ] }); createWeb3Modal({ - projectId, + projectId: PROJECT_ID, wagmiConfig, -}) \ No newline at end of file +}); diff --git a/src/lib/webappSettings.ts b/src/lib/webappSettings.ts index d647761..4b8ad6c 100644 --- a/src/lib/webappSettings.ts +++ b/src/lib/webappSettings.ts @@ -1,13 +1,25 @@ import compiledCircuit from "../../axiom/data/compiled.json"; import inputs from "../../axiom/data/inputs.json"; import AverageBalanceAbi from "./abi/AverageBalance.json"; +import { chainIdToExplorerBaseUrl, getProviderClientSide } from "./utils"; + +export const PROJECT_ID = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID as string; +export const CHAIN_ID = "11155111"; export const WebappSettings = { compiledCircuit, inputs, - provider: process.env.NEXT_PUBLIC_PROVIDER_URI_SEPOLIA as string, - chainId: "11155111", + provider: getProviderClientSide(CHAIN_ID), + chainId: CHAIN_ID, callbackTarget: "0x50F2D5c9a4A35cb922a631019287881f56A00ED5", callbackAbi: AverageBalanceAbi, - explorerBaseUrl: "https://explorer.axiom.xyz/v2/sepolia", -} \ No newline at end of file + explorerBaseUrl: chainIdToExplorerBaseUrl(CHAIN_ID), +} + +if (WebappSettings.provider === "") { + throw new Error(`Please set the NEXT_PUBLIC_PROVIDER_URI_${CHAIN_ID} environment variable to a valid provider URI.`); +} + +if (WebappSettings.callbackTarget === "") { + throw new Error("AverageBalance contract has not yet been deployed on this chain. Deploy it first and insert the deployed contract address into the `WebappSettings.callbackTarget` variable."); +}