Skip to content

Commit

Permalink
Merge pull request #221 from ubq-testing/development
Browse files Browse the repository at this point in the history
Fix infinite load on non-web3 friendly browsers
  • Loading branch information
rndquu authored May 27, 2024
2 parents adf7277 + 3dcd677 commit df00543
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 39 deletions.
5 changes: 1 addition & 4 deletions cypress/e2e/claim-portal-failure.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ describe("Claims Portal Failures", () => {
});

it("should handle no connected signer", () => {
/**
* This covers a user declining to connect their wallet
*/
cy.get("#additionalDetails", { timeout: 15000 }).should("be.visible").invoke("click");

cy.get("button[id='make-claim']").should("be.visible").click();
cy.get("#invalidator").should("not.be.visible");
cy.get("#claim-loader").should("not.be.visible");
cy.get("#view-claim").should("not.be.visible").and("include.text", "View Claim");

cy.get("body").should("contain.text", "This reward is not for you");
cy.get("body").should("contain.text", "Please connect your wallet to claim this reward.");
});
});

Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/claim-portal-non-web3.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe("Claims Portal Non-Web3", () => {
cy.get("#claim-loader").should("not.be.visible");
cy.get("#view-claim").should("not.be.visible");

cy.get("body", { timeout: 3000 }).should("contain.text", "Please use a web3 enabled browser to collect this reward.");
cy.get("body", { timeout: 3000 }).should("contain.text", "Please use a mobile-friendly Web3 browser such as MetaMask to collect this reward");
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion cypress/scripts/anvil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { spawn } from "child_process";

const url = "http://localhost:8545";

const anvil = spawn("anvil", ["--chain-id", "31337", "--fork-url", "https://gnosis.drpc.org", "--host", "127.0.0.1", "--port", "8545"], {
const anvil = spawn("anvil", ["--chain-id", "31337", "--fork-url", "https://gnosis-pokt.nodies.app", "--host", "127.0.0.1", "--port", "8545"], {
stdio: "inherit",
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { decodePermits } from "@ubiquibot/permit-generation/handlers";
import { Permit } from "@ubiquibot/permit-generation/types";
import { app, AppState } from "../app-state";
import { useFastestRpc } from "../rpc-optimization/get-optimal-provider";
import { buttonController, toaster } from "../toaster";
import { toaster } from "../toaster";
import { connectWallet } from "../web3/connect-wallet";
import { checkRenderInvalidatePermitAdminControl, checkRenderMakeClaimControl } from "../web3/erc20-permit";
import { verifyCurrentNetwork } from "../web3/verify-current-network";
Expand All @@ -30,26 +30,32 @@ export async function readClaimDataFromUrl(app: AppState) {

app.claims = decodeClaimData(base64encodedTxData);
app.claimTxs = await getClaimedTxs(app);

try {
app.provider = await useFastestRpc(app);
} catch (e) {
toaster.create("error", `${e}`);
}

if (window.ethereum) {
try {
app.signer = await connectWallet();
} catch (error) {
/* empty */
}
window.ethereum.on("accountsChanged", () => {
try {
app.signer = await connectWallet();
} catch (error) {
/* 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);
});
} else {
buttonController.hideAll();
toaster.create("info", "Please use a web3 enabled browser to collect this reward.");
} catch (err) {
/*
* handled feedback upstream already
* buttons are hidden and non-web3 infinite toast exists
*/
}

displayRewardDetails();
displayRewardPagination();

Expand Down
10 changes: 6 additions & 4 deletions static/scripts/rewards/toaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export const viewClaimButton = document.getElementById("view-claim") as HTMLButt
const notifications = document.querySelector(".notifications") as HTMLUListElement;
export const buttonController = new ButtonController(controls);

function createToast(meaning: keyof typeof toaster.icons, text: string) {
function createToast(meaning: keyof typeof toaster.icons, text: string, timeout: number = 5000) {
if (meaning != "info") buttonController.hideLoader();
const toastDetails = {
timer: 5000,
timer: timeout,
} as {
timer: number;
timeoutId?: NodeJS.Timeout;
Expand All @@ -43,8 +43,10 @@ function createToast(meaning: keyof typeof toaster.icons, text: string) {

notifications.appendChild(toastContent); // Append the toast to the notification ul

// Setting a timeout to remove the toast after the specified duration
toastDetails.timeoutId = setTimeout(() => removeToast(toastContent, toastDetails.timeoutId), toastDetails.timer);
if (timeout !== Infinity) {
// Setting a timeout to remove the toast after the specified duration
toastDetails.timeoutId = setTimeout(() => removeToast(toastContent, toastDetails.timeoutId), toastDetails.timer);
}
}

function removeToast(toast: HTMLElement, timeoutId?: NodeJS.Timeout) {
Expand Down
36 changes: 25 additions & 11 deletions static/scripts/rewards/web3/connect-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,32 @@ export async function connectWallet(): Promise<JsonRpcSigner | null> {

return signer;
} catch (error: unknown) {
// For testing purposes
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (window.location.href.includes("localhost") && (window as any).signer) return (window as any).signer;

if (error instanceof Error) {
console.error(error);
if (error?.message?.includes("missing provider")) {
toaster.create("info", "Please use a web3 enabled browser to collect this reward.");
} else {
toaster.create("info", "Please connect your wallet to collect this reward.");
return connectErrorHandler(error);
}
}

function connectErrorHandler(error: unknown) {
if (error instanceof Error) {
console.error(error);
if (error?.message?.includes("missing provider")) {
// mobile browsers don't really support window.ethereum
const mediaQuery = window.matchMedia("(max-width: 768px)");

if (mediaQuery.matches) {
toaster.create("warning", "Please use a mobile-friendly Web3 browser such as MetaMask to collect this reward", Infinity);
} else if (!window.ethereum) {
toaster.create("warning", "Please use a web3 enabled browser to collect this reward.", Infinity);
buttonController.hideAll();
}
} else {
toaster.create("error", error.message);
}
return null;
} else {
toaster.create("error", "An unknown error occurred.");
}

if (window.location.href.includes("localhost")) {
return (window as unknown as { signer: ethers.providers.JsonRpcSigner }).signer;
}
return null;
}
21 changes: 14 additions & 7 deletions static/scripts/rewards/web3/erc20-permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { erc20Abi, permit2Abi } from "../abis";
import { app, AppState } from "../app-state";
import { permit2Address } from "../constants";
import { supabase } from "../render-transaction/read-claim-data-from-url";
import { buttonController, errorToast, getMakeClaimButton, MetaMaskError, toaster } from "../toaster";
import { MetaMaskError, buttonController, errorToast, getMakeClaimButton, toaster } from "../toaster";
import { connectWallet } from "./connect-wallet";

export async function fetchTreasury(permit: Permit): Promise<{ balance: BigNumber; allowance: BigNumber; decimals: number; symbol: string }> {
let balance: BigNumber, allowance: BigNumber, decimals: number, symbol: string;
Expand Down Expand Up @@ -58,6 +59,9 @@ async function checkPermitClaimability(app: AppState): Promise<boolean> {

async function transferFromPermit(permit2Contract: Contract, app: AppState) {
const reward = app.reward;
const signer = app.signer;
if (!signer) return null;

try {
const tx = await permit2Contract.permitTransferFrom(
{
Expand Down Expand Up @@ -101,6 +105,7 @@ async function waitForTransaction(tx: TransactionResponse) {
buttonController.hideLoader();
buttonController.hideMakeClaim();
console.log(receipt.transactionHash);

return receipt;
} catch (error: unknown) {
if (error instanceof Error) {
Expand All @@ -113,23 +118,25 @@ async function waitForTransaction(tx: TransactionResponse) {

export function claimErc20PermitHandlerWrapper(app: AppState) {
return async function claimErc20PermitHandler() {
const signer = await connectWallet();
if (!signer) {
buttonController.hideAll();
toaster.create("error", `Please connect your wallet to claim this reward.`);
return;
}

buttonController.hideMakeClaim();
buttonController.showLoader();

const isPermitClaimable = await checkPermitClaimability(app);
if (!isPermitClaimable) return;

if (!app.signer) return;

const permit2Contract = new ethers.Contract(permit2Address, permit2Abi, app.signer);
const permit2Contract = new ethers.Contract(permit2Address, permit2Abi, signer);
if (!permit2Contract) return;

const tx = await transferFromPermit(permit2Contract, app);
if (!tx) return;

// buttonController.showLoader();
// buttonController.hideMakeClaim();

const receipt = await waitForTransaction(tx);
if (!receipt) return;

Expand Down

0 comments on commit df00543

Please sign in to comment.