Skip to content

Commit

Permalink
feat: decode metamask transaction error
Browse files Browse the repository at this point in the history
  • Loading branch information
ariesgun committed Oct 25, 2024
1 parent e555598 commit eb07da2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
9 changes: 9 additions & 0 deletions static/scripts/rewards/toaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,13 @@ export type MetaMaskError = {
hex: "0x012c5a";
};
};
error: {
code: string;
message: string;
data: {
code: string;
message: string;
data: string;
};
};
};
5 changes: 3 additions & 2 deletions static/scripts/rewards/web3/erc20-permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { buttonController, getMakeClaimButton, viewClaimButton } from "../button
import { toaster, errorToast, MetaMaskError } from "../toaster";
import { connectWallet } from "./connect-wallet";
import { convertToNetworkId } from "./use-rpc-handler";
import { decodeError } from "./error-decoder";

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 @@ -89,8 +90,8 @@ export async function transferFromPermit(permit2Contract: Contract, reward: Perm
buttonController.hideLoader();
buttonController.showMakeClaim();
} else {
// Handle other errors
console.error("Error in permitTransferFrom:", e);
const { errorname, message } = decodeError(permit2Contract, e);
console.error(`Error in permitTransferFrom: ${errorname} [ ${message} ]`);
errorToast(e, e.reason);
}
}
Expand Down
21 changes: 17 additions & 4 deletions static/scripts/rewards/web3/erc721-permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { ERC721Permit } from "@ubiquibot/permit-generation/types";
import { BigNumber, ethers } from "ethers";
import { nftRewardAbi } from "../abis/nft-reward-abi";
import { app } from "../app-state";
import { toaster } from "../toaster";
import { errorToast, MetaMaskError, toaster } from "../toaster";
import { buttonController, getMakeClaimButton } from "../button-controller";
import { connectWallet } from "./connect-wallet";
import { decodeError } from "./error-decoder";

export function claimErc721PermitHandler(reward: ERC721Permit) {
return async function claimHandler() {
Expand All @@ -31,9 +32,11 @@ export function claimErc721PermitHandler(reward: ERC721Permit) {
}

buttonController.showLoader();
try {
const nftContract = new ethers.Contract(reward.tokenAddress, nftRewardAbi, signer);

const nftContract = new ethers.Contract(reward.tokenAddress, nftRewardAbi, signer);
if (!nftContract) return;

try {
const tx: TransactionResponse = await nftContract.safeMint(
{
beneficiary: reward.beneficiary,
Expand Down Expand Up @@ -62,7 +65,17 @@ export function claimErc721PermitHandler(reward: ERC721Permit) {
} catch (error: unknown) {
console.error(error);
if (error instanceof Error) {
toaster.create("error", `Error claiming NFT: ${error.message}`);
const e = error as unknown as MetaMaskError;
if (e.code == "ACTION_REJECTED") {
// Handle the user rejection case
toaster.create("info", `Transaction was not sent because it was rejected by the user.`);
buttonController.hideLoader();
buttonController.showMakeClaim();
} else {
const { errorname, message } = decodeError(nftContract, e);
console.error(`Error claiming NFT: ${errorname} [ ${message} ]`);
errorToast(e, e.reason);
}
} else if (typeof error === "string") {
toaster.create("error", `Error claiming NFT: ${error}`);
} else {
Expand Down
24 changes: 24 additions & 0 deletions static/scripts/rewards/web3/error-decoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Contract } from "ethers";
import { MetaMaskError } from "../toaster";

export function decodeError(contract: Contract, err: MetaMaskError) {
const errordata = err.error?.data?.data;
const iface = contract.interface;
const selecter = errordata.slice(0, 10);
const res = iface.decodeErrorResult(selecter, errordata);
const errorfragments = iface.getError(selecter);

let message;
if (errorfragments.inputs.length > 0) {
message = errorfragments.inputs
.map((input, index) => {
return `${input.name}: ${res[index].toString()}`;
})
.join(", ");
}

return {
errorname: errorfragments.name,
message: message,
};
}

0 comments on commit eb07da2

Please sign in to comment.