From db22f567d6ff0b1c483c54382532c384fca86ffe Mon Sep 17 00:00:00 2001 From: zugdev Date: Tue, 15 Oct 2024 01:13:02 -0300 Subject: [PATCH] feat: centralize button visibility responsibility and delete a lot of redundant code --- .../read-claim-data-from-url.ts | 65 ++++++++++++++----- .../render-transaction/render-transaction.ts | 11 +--- .../web3/handle-if-on-correct-network.ts | 9 --- .../rewards/web3/not-on-correct-network.ts | 18 ----- static/scripts/rewards/web3/switch-network.ts | 2 - .../rewards/web3/verify-current-network.ts | 23 ------- 6 files changed, 48 insertions(+), 80 deletions(-) delete mode 100644 static/scripts/rewards/web3/handle-if-on-correct-network.ts delete mode 100644 static/scripts/rewards/web3/not-on-correct-network.ts delete mode 100644 static/scripts/rewards/web3/verify-current-network.ts diff --git a/static/scripts/rewards/render-transaction/read-claim-data-from-url.ts b/static/scripts/rewards/render-transaction/read-claim-data-from-url.ts index 225475c7..8e6c7682 100644 --- a/static/scripts/rewards/render-transaction/read-claim-data-from-url.ts +++ b/static/scripts/rewards/render-transaction/read-claim-data-from-url.ts @@ -2,14 +2,16 @@ import { createClient } from "@supabase/supabase-js"; import { decodePermits } from "@ubiquibot/permit-generation/handlers"; import { Permit } from "@ubiquibot/permit-generation/types"; import { app, AppState } from "../app-state"; -import { toaster } from "../toaster"; +import { buttonController, toaster } from "../toaster"; import { connectWallet } from "../web3/connect-wallet"; import { checkRenderInvalidatePermitAdminControl, checkRenderMakeClaimControl } from "../web3/erc20-permit"; -import { verifyCurrentNetwork } from "../web3/verify-current-network"; import { claimRewardsPagination } from "./claim-rewards-pagination"; import { renderTransaction } from "./render-transaction"; import { setClaimMessage } from "./set-claim-message"; import { useRpcHandler } from "../web3/use-rpc-handler"; +import { switchNetwork } from "../web3/switch-network"; +import { ethers } from "ethers"; +import { getNetworkName, NetworkId } from "@ubiquity-dao/rpc-handler"; declare const SUPABASE_URL: string; declare const SUPABASE_ANON_KEY: string; @@ -47,30 +49,57 @@ export async function readClaimDataFromUrl(app: AppState) { /* empty */ } - try { - // this would throw on mobile browsers & non-web3 browsers - window?.ethereum.on("accountsChanged", () => { - checkRenderMakeClaimControl(app).catch(console.error); - checkRenderInvalidatePermitAdminControl(app).catch(console.error); - }); - } catch (err) { - /* - * handled feedback upstream already - * buttons are hidden and non-web3 infinite toast exists - */ - } + await updateButtonVisibility(app); displayRewardDetails(); displayRewardPagination(); await renderTransaction(); - if (app.networkId !== null) { - await verifyCurrentNetwork(app.networkId); - } else { - throw new Error("Network ID is null"); +} + +async function updateButtonVisibility(app: AppState) { + try { + const currentNetworkId = parseInt(await window.ethereum.request({ method: "eth_chainId" }), 16); + + if (currentNetworkId !== app.networkId) { + console.warn(`Incorrect network. Expected ${app.networkId}, but got ${currentNetworkId}.`); + buttonController.hideAll(); // Hide all buttons if the network is incorrect + toaster.create("error", `This dApp currently does not support payouts for network ID ${currentNetworkId}`); + + // Try switching to the propper network id + switchNetwork(new ethers.providers.Web3Provider(window.ethereum), app.reward.networkId).catch((error) => { + console.error(error); + if (app.networkId !== null) { + toaster.create("error", `Please switch to the ${getNetworkName(String(app.networkId) as NetworkId)} network to claim this reward.`); + } + }); + + return; // Stop further checks if the network is incorrect + } + + await checkRenderMakeClaimControl(app); + await checkRenderInvalidatePermitAdminControl(app); + } catch (error) { + console.error("Error updating button visibility:", error); + buttonController.hideAll(); // Hide all buttons if there's an error } } +// Below is a listener that updates buttons on account/network change +if (window.ethereum) { + // Handle account changes + window.ethereum.on("accountsChanged", async () => { + await updateButtonVisibility(app); + }); + + // Handle network changes + window.ethereum.on("chainChanged", async () => { + await updateButtonVisibility(app); + }); +} else { + console.warn("Ethereum provider not detected."); +} + async function getClaimedTxs(app: AppState): Promise> { const txs: Record = Object.create(null); for (const claim of app.claims) { diff --git a/static/scripts/rewards/render-transaction/render-transaction.ts b/static/scripts/rewards/render-transaction/render-transaction.ts index d19583d2..9d8e9cba 100644 --- a/static/scripts/rewards/render-transaction/render-transaction.ts +++ b/static/scripts/rewards/render-transaction/render-transaction.ts @@ -2,9 +2,8 @@ import { ERC20Permit, Permit, TokenType } from "@ubiquibot/permit-generation/typ import { networkExplorers } from "@ubiquity-dao/rpc-handler"; import { app } from "../app-state"; import { buttonController, getMakeClaimButton, viewClaimButton } from "../toaster"; -import { checkRenderInvalidatePermitAdminControl, claimErc20PermitHandlerWrapper, fetchTreasury } from "../web3/erc20-permit"; +import { claimErc20PermitHandlerWrapper, fetchTreasury } from "../web3/erc20-permit"; import { claimErc721PermitHandler } from "../web3/erc721-permit"; -import { verifyCurrentNetwork } from "../web3/verify-current-network"; import { insertErc20PermitTableData, insertErc721PermitTableData } from "./insert-table-data"; import { renderEnsName } from "./render-ens-name"; import { renderNftSymbol, renderTokenSymbol } from "./render-token-symbol"; @@ -26,8 +25,6 @@ export async function renderTransaction(): Promise { return false; } - verifyCurrentNetwork(app.reward.networkId).catch(console.error); - if (isErc20Permit(app.reward)) { const treasury = await fetchTreasury(app.reward); table.setAttribute(`data-additional-data-size`, "small"); @@ -47,16 +44,10 @@ export async function renderTransaction(): Promise { const toElement = document.getElementById(`rewardRecipient`) as Element; renderEnsName({ element: toElement, address: app.reward.beneficiary, networkId: app.networkId }).catch(console.error); - if (app.provider) { - checkRenderInvalidatePermitAdminControl(app).catch(console.error); - } - if (app.claimTxs[app.reward.nonce.toString()] !== undefined) { buttonController.showViewClaim(); viewClaimButton.addEventListener("click", () => window.open(`${app.currentExplorerUrl}/tx/${app.claimTxs[app.reward.nonce.toString()]}`)); } else if (window.ethereum) { - // requires wallet connection to claim - buttonController.showMakeClaim(); getMakeClaimButton().addEventListener("click", claimErc20PermitHandlerWrapper(app)); } diff --git a/static/scripts/rewards/web3/handle-if-on-correct-network.ts b/static/scripts/rewards/web3/handle-if-on-correct-network.ts deleted file mode 100644 index a9d17400..00000000 --- a/static/scripts/rewards/web3/handle-if-on-correct-network.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { buttonController } from "../toaster"; - -export function handleIfOnCorrectNetwork(currentNetworkId: number, desiredNetworkId: number) { - if (desiredNetworkId === currentNetworkId) { - buttonController.showMakeClaim(); - } else { - buttonController.hideMakeClaim(); - } -} diff --git a/static/scripts/rewards/web3/not-on-correct-network.ts b/static/scripts/rewards/web3/not-on-correct-network.ts deleted file mode 100644 index d04a6334..00000000 --- a/static/scripts/rewards/web3/not-on-correct-network.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ethers } from "ethers"; -import { getNetworkName } from "@ubiquity-dao/rpc-handler"; -import { buttonController, toaster } from "../toaster"; -import { switchNetwork } from "./switch-network"; - -export function notOnCorrectNetwork(currentNetworkId: number, desiredNetworkId: number, web3provider: ethers.providers.Web3Provider) { - if (currentNetworkId !== desiredNetworkId) { - const networkName = getNetworkName(desiredNetworkId); - if (!networkName) { - toaster.create("error", `This dApp currently does not support payouts for network ID ${desiredNetworkId}`); - } - switchNetwork(web3provider, desiredNetworkId).catch((error) => { - console.error(error); - toaster.create("error", `Please switch to the ${networkName} network to claim this reward.`); - buttonController.hideAll(); - }); - } -} diff --git a/static/scripts/rewards/web3/switch-network.ts b/static/scripts/rewards/web3/switch-network.ts index 98266c2f..51ddae7c 100644 --- a/static/scripts/rewards/web3/switch-network.ts +++ b/static/scripts/rewards/web3/switch-network.ts @@ -1,11 +1,9 @@ import { ethers } from "ethers"; import { addNetwork } from "./add-network"; -import { buttonController } from "../toaster"; export async function switchNetwork(provider: ethers.providers.Web3Provider, networkId: number): Promise { try { await provider.send("wallet_switchEthereumChain", [{ chainId: "0x" + networkId.toString(16) }]); - buttonController.showMakeClaim(); return true; } catch (error: unknown) { // Add network if it doesn't exist. diff --git a/static/scripts/rewards/web3/verify-current-network.ts b/static/scripts/rewards/web3/verify-current-network.ts deleted file mode 100644 index 8d1e530d..00000000 --- a/static/scripts/rewards/web3/verify-current-network.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ethers } from "ethers"; -import { buttonController } from "../toaster"; -import { handleIfOnCorrectNetwork } from "./handle-if-on-correct-network"; -import { notOnCorrectNetwork } from "./not-on-correct-network"; - -// verifyCurrentNetwork checks if the user is on the correct network and displays an error if not -export async function verifyCurrentNetwork(desiredNetworkId: number) { - if (!window.ethereum) { - buttonController.hideAll(); - return; - } - - const web3provider = new ethers.providers.Web3Provider(window.ethereum); - - const network = await web3provider.getNetwork(); - const currentNetworkId = network.chainId; - - // watch for network changes - window.ethereum.on("chainChanged", (newNetworkId: T | string) => handleIfOnCorrectNetwork(parseInt(newNetworkId as string, 16), desiredNetworkId)); - - // if its not on ethereum mainnet, gnosis, or goerli, display error - notOnCorrectNetwork(currentNetworkId, desiredNetworkId, web3provider); -}