From 18adb4e146fbfeb56ac890814b5966411a4e01a3 Mon Sep 17 00:00:00 2001 From: zugdev Date: Fri, 13 Dec 2024 00:51:44 -0300 Subject: [PATCH] feat: all providers --- .env.example | 2 +- build/esbuild-build.ts | 23 ++++++++++++++++++++ static/main.ts | 49 +++++++++++++++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/.env.example b/.env.example index e49d79a..ba172bc 100644 --- a/.env.example +++ b/.env.example @@ -1 +1 @@ -MY_SECRET="MY_SECRET" +ALCHEMY_KEY="" \ No newline at end of file diff --git a/build/esbuild-build.ts b/build/esbuild-build.ts index 00fc141..ee81595 100644 --- a/build/esbuild-build.ts +++ b/build/esbuild-build.ts @@ -1,4 +1,6 @@ +import { config } from "dotenv"; import esbuild, { BuildOptions } from "esbuild"; +config(); const ENTRY_POINTS = { typescript: ["static/main.ts"], @@ -14,6 +16,9 @@ export const esbuildOptions: BuildOptions = { minify: false, loader: Object.fromEntries(DATA_URL_LOADERS.map((ext) => [ext, "dataurl"])), outdir: "static/dist", + define: createEnvDefines(["ALCHEMY_KEY"], { + ALCHEMY_KEY: process.env.ALCHEMY_KEY + }) }; async function runBuild() { @@ -27,3 +32,21 @@ async function runBuild() { } void runBuild(); + +function createEnvDefines(environmentVariables: string[], generatedAtBuild: Record): Record { + const defines: Record = {}; + for (const name of environmentVariables) { + const envVar = process.env[name]; + if (envVar !== undefined) { + defines[name] = JSON.stringify(envVar); + } else { + throw new Error(`Missing environment variable: ${name}`); + } + } + for (const key in generatedAtBuild) { + if (Object.prototype.hasOwnProperty.call(generatedAtBuild, key)) { + defines[key] = JSON.stringify(generatedAtBuild[key]); + } + } + return defines; +} diff --git a/static/main.ts b/static/main.ts index a59a716..44aa1e5 100644 --- a/static/main.ts +++ b/static/main.ts @@ -1,11 +1,14 @@ import { createAppKit } from "@reown/appkit"; import { Ethers5Adapter } from "@reown/appkit-adapter-ethers5"; -import { gnosis, mainnet, polygon, optimism, arbitrum, base, bsc, blast, zksync, avalanche, celo, worldchain, zora } from "@reown/appkit/networks"; +import { gnosis, mainnet, polygon, optimism, arbitrum, base, bsc, blast, zksync, avalanche, worldchain } from "@reown/appkit/networks"; import { ethers } from "ethers"; import { renderErrorInModal } from "./display-popup-modal"; import { updateTokens } from "./populate-dropdown"; import { setupApproveButton, setupRevokeButton, setupValidityListener } from "./handle-approval"; +// passed in at runtime +declare const ALCHEMY_KEY: string; + // All unhandled errors are caught and displayed in a modal window.addEventListener("error", (event: ErrorEvent) => renderErrorInModal(event.error)); @@ -24,13 +27,25 @@ const metadata = { icons: ["https://avatars.githubusercontent.com/u/76412717"], }; -// create provider & signer for gnosis -export const provider = new ethers.providers.JsonRpcProvider("https://eth.llamarpc.com"); -export let userSigner: ethers.Signer; +const alchemyKey = ALCHEMY_KEY || ""; + +const providersUrl: { [key: string]: string } = { + 100: alchemyKey ? `https://gnosis-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://rpc.gnosischain.com", + 1: alchemyKey ? `https://eth-mainnet.alchemyapi.io/v2/${alchemyKey}` : "https://eth.llamarpc.com", + 137: alchemyKey ? `https://polygon-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://polygon.llamarpc.com", + 10: alchemyKey ? `https://opt-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://optimism.llamarpc.com", + 42161: alchemyKey ? `https://arb-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://arbitrum.llamarpc.com", + 8453: alchemyKey ? `https://base-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://base.llamarpc.com", + 56: alchemyKey ? `https://bnb-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://binance.llamarpc.com", + 81457: alchemyKey ? `https://blast-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://blast.drpc.org", + 324: alchemyKey ? `https://zksync-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://mainnet.era.zksync.io", + 43114: alchemyKey ? `https://avax-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://rpc.ankr.com/avalanche", + 480: alchemyKey ? `https://worldchain-mainnet.g.alchemy.com/v2/${alchemyKey}` : "https://rpc.worldchain.network" +}; export const appState = createAppKit({ adapters: [new Ethers5Adapter()], - networks: [gnosis, mainnet, polygon, optimism, arbitrum, base, bsc, blast, zksync, avalanche, celo, worldchain, zora], + networks: [gnosis, mainnet, polygon, optimism, arbitrum, base, bsc, blast, zksync, avalanche, worldchain], defaultNetwork: gnosis, metadata, projectId, @@ -39,34 +54,48 @@ export const appState = createAppKit({ }, }); +// create provider & signer for gnosis +export let provider = new ethers.providers.JsonRpcProvider(providersUrl[appState.getCaipNetwork().id]); +export let userSigner: ethers.Signer; + async function waitForConnection() { return new Promise((resolve) => { const interval = setInterval(() => { if (appState.getIsConnectedState()) { userSigner = provider.getSigner(appState.getAddress()); - console.log(`User connected: ${appState.getAddress()}`); + console.log(`user connected: ${appState.getAddress()}`); clearInterval(interval); resolve(); } else { - console.log("Waiting for user to connect..."); + console.log("waiting for user to connect..."); } }, 1000); }); } function handleNetworkSwitch() { - appState.subscribeCaipNetworkChange(async (newNetwork) => { - console.log("Network changed to:", newNetwork?.id); + appState.subscribeCaipNetworkChange(async (newNetwork: { id: string; name: string}) => { + switchProvider(newNetwork?.id); updateTokens(); // update known tokens on the dropdown setupApproveButton(); // setup approve button setupRevokeButton(); // setup revoke button }); } +function switchProvider(network: string) { + const url = providersUrl[network]; + if (url) { + provider = new ethers.providers.JsonRpcProvider(url); + userSigner = provider.getSigner(appState.getAddress()); + console.log(`switched provider to ${network}`); + } else { + console.error(`No URL found for network: ${network}`); + } +} + export async function mainModule() { try { setupValidityListener(); // setup amount and token validity listeners - console.log("Provider:", provider); updateTokens(); // update known tokens on the dropdown setupApproveButton(); // setup approve button setupRevokeButton(); // setup revoke button