bug: mint button not triggering in dev hosted (#170)
* feat: parse error code using abi * feat: add prepare error treatment on mint flow
This commit is contained in:
parent
d6f8d047c8
commit
fbee0945fd
|
|
@ -1,13 +1,27 @@
|
|||
import {
|
||||
ErrorDescription as InterfaceErrorDescription,
|
||||
Result as InterfaceResult,
|
||||
} from '@ethersproject/abi/lib/interface';
|
||||
import { BytesLike } from 'ethers';
|
||||
import { Ethereum } from '../ethereum';
|
||||
|
||||
enum CollectionRoles {
|
||||
Owner,
|
||||
Verifier,
|
||||
}
|
||||
|
||||
enum TokenRoles {
|
||||
Controller,
|
||||
}
|
||||
|
||||
export const FleekERC721 = {
|
||||
contract: Ethereum.getContract('FleekERC721'),
|
||||
|
||||
async mint(
|
||||
params: FleekERC721.MintParams,
|
||||
provider: Ethereum.Providers
|
||||
): Promise<void> {
|
||||
const contract = Ethereum.getContract('FleekERC721', provider);
|
||||
|
||||
const response = await contract.mint(
|
||||
const response = await this.contract.connect(provider).mint(
|
||||
params.owner,
|
||||
params.name,
|
||||
params.description.replaceAll(/\n/g, '\\n'), //replace break lines with \\n so it doesn't break the json,
|
||||
|
|
@ -39,6 +53,83 @@ export const FleekERC721 = {
|
|||
// TODO: fetch last token id
|
||||
return 7;
|
||||
},
|
||||
|
||||
parseError(error: BytesLike): FleekERC721.TransactionError {
|
||||
try {
|
||||
if (!error) throw new Error('Empty error');
|
||||
|
||||
const description = this.contract.interface.parseError(error);
|
||||
const result = this.contract.interface.decodeErrorResult(
|
||||
description.signature,
|
||||
error
|
||||
);
|
||||
|
||||
let message: string;
|
||||
|
||||
switch (description.signature) {
|
||||
case 'ContractIsNotPausable()':
|
||||
message = 'This contract is not pausable';
|
||||
break;
|
||||
|
||||
case 'ContractIsNotPaused()':
|
||||
message = 'This contract is not paused';
|
||||
break;
|
||||
|
||||
case 'ContractIsPaused()':
|
||||
message = 'This contract is paused';
|
||||
break;
|
||||
|
||||
case 'MustBeTokenOwner(uint256)':
|
||||
message = `You must be the token #${result.tokenId} owner`;
|
||||
break;
|
||||
|
||||
case 'MustHaveAtLeastOneOwner()':
|
||||
message = 'You must have at least one owner';
|
||||
break;
|
||||
|
||||
case 'MustHaveCollectionRole(uint8)':
|
||||
message = `You must have a collection role "${
|
||||
CollectionRoles[result.role]
|
||||
}" to mint`;
|
||||
break;
|
||||
|
||||
case 'MustHaveTokenRole(uint256,uint8)':
|
||||
message = `You must have a token role "${
|
||||
TokenRoles[result.role]
|
||||
}" on token #${result.tokenId}`;
|
||||
break;
|
||||
|
||||
case 'PausableIsSetTo(bool)':
|
||||
message = `Pausable is set to "${result.isPausable}"`;
|
||||
break;
|
||||
|
||||
case 'RoleAlreadySet()':
|
||||
message = `Role is already set`;
|
||||
break;
|
||||
|
||||
case 'ThereIsNoTokenMinted()':
|
||||
message = `There is no token minted`;
|
||||
break;
|
||||
|
||||
default:
|
||||
message = 'Unknown error';
|
||||
}
|
||||
|
||||
return {
|
||||
message,
|
||||
description,
|
||||
result,
|
||||
isIdentified: true,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
message: 'Unknown error',
|
||||
description: null,
|
||||
result: null,
|
||||
isIdentified: false,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export namespace FleekERC721 {
|
||||
|
|
@ -61,4 +152,11 @@ export namespace FleekERC721 {
|
|||
}
|
||||
];
|
||||
};
|
||||
|
||||
export type TransactionError = {
|
||||
message: string;
|
||||
description: InterfaceErrorDescription | null;
|
||||
result: InterfaceResult | null;
|
||||
isIdentified: boolean;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { ComboboxItem, DropdownItem } from '@/components';
|
||||
import { GithubState } from '@/store';
|
||||
import { EthereumHooks } from '@/integrations';
|
||||
import { createContext } from '@/utils';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ComboboxItem, DropdownItem } from '@/components';
|
||||
import { Ethereum, EthereumHooks } from '@/integrations';
|
||||
import { GithubState } from '@/store';
|
||||
import { createContext } from '@/utils';
|
||||
|
||||
export type MintContext = {
|
||||
selectedUserOrg: ComboboxItem;
|
||||
repositoryName: GithubState.Repository;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ type NftCardProps = {
|
|||
message: string;
|
||||
buttonText: string;
|
||||
leftIconButton?: React.ReactNode;
|
||||
onClick: () => void;
|
||||
onClick?: () => void;
|
||||
isLoading: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ export const NftCard: React.FC<NftCardProps> = ({
|
|||
onClick={onClick}
|
||||
leftIcon={leftIconButton}
|
||||
isLoading={isLoading}
|
||||
isDisabled={isLoading}
|
||||
isDisabled={isLoading || !onClick}
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Icon, IconButton, Stepper } from '@/components';
|
||||
import { useTransactionCost } from '@/hooks';
|
||||
import { FleekERC721 } from '@/integrations';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
import { ethers } from 'ethers';
|
||||
import { useMemo } from 'react';
|
||||
|
|
@ -8,7 +9,7 @@ import { NftCard } from '../nft-card';
|
|||
export const MintPreview = () => {
|
||||
const { prevStep } = Stepper.useContext();
|
||||
const {
|
||||
prepare: { status: prepareStatus, data: prepareData },
|
||||
prepare: { status: prepareStatus, data: prepareData, error: prepareError },
|
||||
write: { status: writeStatus, write },
|
||||
transaction: { status: transactionStatus },
|
||||
} = Mint.useTransactionContext();
|
||||
|
|
@ -24,6 +25,18 @@ export const MintPreview = () => {
|
|||
if (isCostLoading || prepareStatus === 'loading')
|
||||
return 'Calculating cost...';
|
||||
|
||||
// TODO: better UI for prepare errors
|
||||
if (prepareError) {
|
||||
const parsedError = FleekERC721.parseError(
|
||||
(prepareError as any).error?.data.data
|
||||
);
|
||||
if (parsedError.isIdentified) {
|
||||
return parsedError.message;
|
||||
}
|
||||
|
||||
return 'An error occurred while preparing the transaction';
|
||||
}
|
||||
|
||||
const formattedCost = ethers.utils.formatEther(cost).slice(0, 9);
|
||||
return `Minting this NFA will cost ${formattedCost} ${currency}.`;
|
||||
}, [prepareData, isCostLoading, prepareStatus]);
|
||||
|
|
@ -59,7 +72,7 @@ export const MintPreview = () => {
|
|||
}
|
||||
message={message}
|
||||
buttonText="Mint NFA"
|
||||
onClick={write!}
|
||||
onClick={write}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue