From fd5744395a5059b0857c32840a63e249348a2ee1 Mon Sep 17 00:00:00 2001 From: Peter Kompasz Date: Mon, 19 Aug 2024 22:09:33 +0200 Subject: [PATCH] feat: network for each permit --- .../read-claim-data-from-url.ts | 14 -------------- .../render-transaction/render-token-symbol.ts | 15 +++++++++++++++ .../render-transaction/render-transaction.ts | 11 +++++------ static/scripts/rewards/web3/connect-wallet.ts | 9 ++++----- static/scripts/rewards/web3/erc20-permit.ts | 9 ++++++++- static/scripts/rewards/web3/erc721-permit.ts | 4 +++- 6 files changed, 35 insertions(+), 27 deletions(-) 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 77e7e95f..4e4d68d6 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 @@ -3,9 +3,7 @@ import { decodePermits } from "@ubiquibot/permit-generation/handlers"; import { Permit } from "@ubiquibot/permit-generation/types"; import { app, AppState } from "../app-state"; import { buttonControllers, toaster } from "../toaster"; -import { connectWallet } from "../web3/connect-wallet"; import { checkRenderInvalidatePermitAdminControl, checkRenderMakeClaimControl } from "../web3/erc20-permit"; -import { verifyCurrentNetwork } from "../web3/verify-current-network"; import { setClaimMessage } from "./set-claim-message"; import { useRpcHandler } from "../web3/use-rpc-handler"; import { renderTransaction } from "./render-transaction"; @@ -42,12 +40,6 @@ export async function readClaimDataFromUrl(app: AppState) { } } - try { - app.signer = await connectWallet(); - } catch (error) { - /* empty */ - } - try { // this would throw on mobile browsers & non-web3 browsers window?.ethereum.on("accountsChanged", () => { @@ -62,12 +54,6 @@ export async function readClaimDataFromUrl(app: AppState) { } await displayRewardsWithDetails(); - - if (app.claims[0].networkId !== null) { - await verifyCurrentNetwork(app.claims[0].networkId); - } else { - throw new Error("Network ID is null"); - } } async function getClaimedTxs(app: AppState): Promise> { diff --git a/static/scripts/rewards/render-transaction/render-token-symbol.ts b/static/scripts/rewards/render-transaction/render-token-symbol.ts index 52ce5cce..9c14a966 100644 --- a/static/scripts/rewards/render-transaction/render-token-symbol.ts +++ b/static/scripts/rewards/render-transaction/render-token-symbol.ts @@ -1,6 +1,8 @@ import { BigNumberish, ethers, utils } from "ethers"; +import { PermitReward } from "@ubiquibot/permit-generation/types"; import { erc20Abi } from "../abis/erc20-abi"; import { app } from "../app-state"; +import { useRpcHandler } from "../web3/use-rpc-handler"; export async function renderTokenSymbol({ table, @@ -9,6 +11,7 @@ export async function renderTokenSymbol({ ownerAddress, amount, explorerUrl, + claim, }: { table: Element; requestedAmountElement: Element; @@ -16,7 +19,13 @@ export async function renderTokenSymbol({ ownerAddress: string; amount: BigNumberish; explorerUrl: string; + claim: PermitReward; }): Promise { + // If the reward is on a different chain we need a new provider + if (app.provider.network.chainId !== claim.networkId) { + console.log("Different network. Switching"); + app.provider = await useRpcHandler(claim); + } const contract = new ethers.Contract(tokenAddress, erc20Abi, app.provider); let symbol, decimals; @@ -58,12 +67,18 @@ export async function renderNftSymbol({ requestedAmountElement, tokenAddress, explorerUrl, + claim, }: { table: Element; requestedAmountElement: Element; tokenAddress: string; explorerUrl: string; + claim: PermitReward; }): Promise { + if (app.provider.network.chainId !== claim.networkId) { + console.log("Different network. Switching"); + app.provider = await useRpcHandler(claim); + } const contract = new ethers.Contract(tokenAddress, erc20Abi, app.provider); let symbol: string; diff --git a/static/scripts/rewards/render-transaction/render-transaction.ts b/static/scripts/rewards/render-transaction/render-transaction.ts index 9b3ba9b6..32f54d4b 100644 --- a/static/scripts/rewards/render-transaction/render-transaction.ts +++ b/static/scripts/rewards/render-transaction/render-transaction.ts @@ -1,15 +1,14 @@ -import { ERC20Permit, Permit, TokenType } from "@ubiquibot/permit-generation/types"; +import { ERC20PermitReward, PermitReward, TokenType } from "@ubiquibot/permit-generation/types"; import { networkExplorers } from "@ubiquity-dao/rpc-handler"; import { app } from "../app-state"; import { buttonControllers, getMakeClaimButton, getViewClaimButton } from "../toaster"; import { checkRenderInvalidatePermitAdminControl, 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"; -export async function renderTransaction(claim: Permit, table: Element): Promise { +export async function renderTransaction(claim: PermitReward, table: Element): Promise { if (!claim) { buttonControllers[claim.nonce].hideAll(); console.log("No reward found"); @@ -20,8 +19,6 @@ export async function renderTransaction(claim: Permit, table: Element): Promise< throw new Error("Missing transaction table"); } - verifyCurrentNetwork(claim.networkId).catch(console.error); - if (isErc20Permit(claim)) { const treasury = await fetchTreasury(claim); table.setAttribute(`data-additional-data-size`, "small"); @@ -36,6 +33,7 @@ export async function renderTransaction(claim: Permit, table: Element): Promise< explorerUrl: networkExplorers[claim.networkId], table, requestedAmountElement, + claim, }); const toElement = table.querySelector(`.reward-recipient`) as Element; @@ -65,6 +63,7 @@ export async function renderTransaction(claim: Permit, table: Element): Promise< explorerUrl: networkExplorers[claim.networkId], table, requestedAmountElement, + claim, }).catch(console.error); const toElement = document.getElementById(`reward-recipient`) as Element; @@ -76,6 +75,6 @@ export async function renderTransaction(claim: Permit, table: Element): Promise< return true; } -function isErc20Permit(permit: Permit): permit is ERC20Permit { +function isErc20Permit(permit: PermitReward): permit is ERC20PermitReward { return permit.tokenType === TokenType.ERC20; } diff --git a/static/scripts/rewards/web3/connect-wallet.ts b/static/scripts/rewards/web3/connect-wallet.ts index 0c988aba..075e0c7c 100644 --- a/static/scripts/rewards/web3/connect-wallet.ts +++ b/static/scripts/rewards/web3/connect-wallet.ts @@ -24,7 +24,7 @@ function mobileCheck() { return checkMobile(navigator.userAgent || navigator.vendor || (window as unknown as { opera: string }).opera); } -export async function connectWallet(): Promise { +export async function connectWallet(networkId: number): Promise { try { const wallet = new ethers.providers.Web3Provider(window.ethereum); @@ -54,7 +54,7 @@ export async function connectWallet(): Promise { // Their wallet provider will auto-prompt due to the call succeeding toaster.create("error", "We have detected potential issues with your in-wallet RPC. Accept the request to replace it with a more reliable one."); } - await addFastestHandlerNetwork(wallet); + await addFastestHandlerNetwork(wallet, networkId); } return signer; @@ -63,9 +63,8 @@ export async function connectWallet(): Promise { } } -async function addFastestHandlerNetwork(wallet: ethers.providers.Web3Provider) { - const networkId = app.networkId ?? (await wallet.getNetwork()).chainId; - const handler = useHandler(networkId); +async function addFastestHandlerNetwork(wallet: ethers.providers.Web3Provider, networkId: number) { + const handler = useHandler(networkId ?? (await wallet.getNetwork()).chainId); let provider = await handler.getFastestRpcProvider(); const appUrl = app.provider?.connection?.url; diff --git a/static/scripts/rewards/web3/erc20-permit.ts b/static/scripts/rewards/web3/erc20-permit.ts index 835b8e70..c8d43681 100644 --- a/static/scripts/rewards/web3/erc20-permit.ts +++ b/static/scripts/rewards/web3/erc20-permit.ts @@ -7,11 +7,17 @@ import { app, AppState } from "../app-state"; import { supabase } from "../render-transaction/read-claim-data-from-url"; import { MetaMaskError, buttonControllers, errorToast, getMakeClaimButton, toaster, getViewClaimButton } from "../toaster"; import { connectWallet } from "./connect-wallet"; +import { verifyCurrentNetwork } from "./verify-current-network"; +import { useRpcHandler } from "./use-rpc-handler"; export async function fetchTreasury(permit: PermitReward): Promise<{ balance: BigNumber; allowance: BigNumber; decimals: number; symbol: string }> { let balance: BigNumber, allowance: BigNumber, decimals: number, symbol: string; try { + if (app.provider.network.chainId !== permit.networkId) { + console.log("Different network. Switching"); + app.provider = await useRpcHandler(permit); + } const tokenAddress = permit.tokenAddress; const tokenContract = new ethers.Contract(tokenAddress, erc20Abi, app.provider); @@ -121,7 +127,8 @@ async function waitForTransaction(tx: TransactionResponse, table: Element) { export function claimErc20PermitHandlerWrapper(table: Element, permit: PermitReward) { return async function claimErc20PermitHandler() { - const signer = await connectWallet(); // we are re-testing the in-wallet rpc at this point + verifyCurrentNetwork(permit.networkId).catch(console.error); + const signer = await connectWallet(permit.networkId); // we are re-testing the in-wallet rpc at this point if (!signer) { // If the signer is unavailable, we will disable button for each reward Object.keys(buttonControllers).forEach((key) => buttonControllers[key].hideAll()); diff --git a/static/scripts/rewards/web3/erc721-permit.ts b/static/scripts/rewards/web3/erc721-permit.ts index 59c7d29d..e0fd6d0c 100644 --- a/static/scripts/rewards/web3/erc721-permit.ts +++ b/static/scripts/rewards/web3/erc721-permit.ts @@ -5,10 +5,12 @@ import { nftRewardAbi } from "../abis/nft-reward-abi"; import { app } from "../app-state"; import { buttonControllers, getMakeClaimButton, toaster } from "../toaster"; import { connectWallet } from "./connect-wallet"; +import { verifyCurrentNetwork } from "./verify-current-network"; export function claimErc721PermitHandler(table: Element, reward: ERC721Permit) { return async function claimHandler() { - const signer = await connectWallet(); + verifyCurrentNetwork(reward.networkId).catch(console.error); + const signer = await connectWallet(reward.networkId); if (!signer) { return; }