Add detailed minting progress indicator (#536)

This commit is contained in:
Daniel 2021-10-05 09:44:16 -07:00 committed by GitHub
parent afa73822d8
commit 3e8bda0a20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 7 deletions

View File

@ -16,7 +16,7 @@ import {
WalletSigner, WalletSigner,
Attribute, Attribute,
} from '@oyster/common'; } from '@oyster/common';
import React from 'react'; import React, { Dispatch, SetStateAction } from 'react';
import { MintLayout, Token } from '@solana/spl-token'; import { MintLayout, Token } from '@solana/spl-token';
import { import {
Keypair, Keypair,
@ -86,6 +86,7 @@ export const mintNFT = async (
creators: Creator[] | null; creators: Creator[] | null;
sellerFeeBasisPoints: number; sellerFeeBasisPoints: number;
}, },
progressCallback: Dispatch<SetStateAction<number>>,
maxSupply?: number, maxSupply?: number,
): Promise<{ ): Promise<{
metadataAccount: StringPublicKey; metadataAccount: StringPublicKey;
@ -120,6 +121,8 @@ export const mintNFT = async (
const { instructions: pushInstructions, signers: pushSigners } = const { instructions: pushInstructions, signers: pushSigners } =
await prepPayForFilesTxn(wallet, realFiles, metadata); await prepPayForFilesTxn(wallet, realFiles, metadata);
progressCallback(1)
const TOKEN_PROGRAM_ID = programIds().token; const TOKEN_PROGRAM_ID = programIds().token;
// Allocate memory for the account // Allocate memory for the account
@ -183,6 +186,7 @@ export const mintNFT = async (
instructions, instructions,
wallet.publicKey.toBase58(), wallet.publicKey.toBase58(),
); );
progressCallback(2)
// TODO: enable when using payer account to avoid 2nd popup // TODO: enable when using payer account to avoid 2nd popup
// const block = await connection.getRecentBlockhash('singleGossip'); // const block = await connection.getRecentBlockhash('singleGossip');
@ -194,6 +198,7 @@ export const mintNFT = async (
// }), // }),
// ); // );
const { txid } = await sendTransactionWithRetry( const { txid } = await sendTransactionWithRetry(
connection, connection,
wallet, wallet,
@ -201,9 +206,11 @@ export const mintNFT = async (
signers, signers,
'single', 'single',
); );
progressCallback(3)
try { try {
await connection.confirmTransaction(txid, 'max'); await connection.confirmTransaction(txid, 'max');
progressCallback(4)
} catch { } catch {
// ignore // ignore
} }
@ -212,6 +219,8 @@ export const mintNFT = async (
// await connection.confirmTransaction(txid, 'max'); // await connection.confirmTransaction(txid, 'max');
await connection.getParsedConfirmedTransaction(txid, 'confirmed'); await connection.getParsedConfirmedTransaction(txid, 'confirmed');
progressCallback(5)
// this means we're done getting AR txn setup. Ship it off to ARWeave! // this means we're done getting AR txn setup. Ship it off to ARWeave!
const data = new FormData(); const data = new FormData();
data.append('transaction', txid); data.append('transaction', txid);
@ -228,7 +237,9 @@ export const mintNFT = async (
realFiles.map(f => data.append('file[]', f)); realFiles.map(f => data.append('file[]', f));
// TODO: convert to absolute file name for image // TODO: convert to absolute file name for image
const result: IArweaveResult = await uploadToArweave(data); const result: IArweaveResult = await uploadToArweave(data);
progressCallback(6)
const metadataFile = result.messages?.find( const metadataFile = result.messages?.find(
m => m.filename === RESERVED_TXN_MANIFEST, m => m.filename === RESERVED_TXN_MANIFEST,
@ -265,6 +276,8 @@ export const mintNFT = async (
1, 1,
), ),
); );
progressCallback(7)
// // In this instruction, mint authority will be removed from the main mint, while // // In this instruction, mint authority will be removed from the main mint, while
// // minting authority will be maintained for the Printing mint (which we want.) // // minting authority will be maintained for the Printing mint (which we want.)
await createMasterEdition( await createMasterEdition(
@ -296,6 +309,8 @@ export const mintNFT = async (
// updateInstructions, // updateInstructions,
// ); // );
progressCallback(8)
const txid = await sendTransactionWithRetry( const txid = await sendTransactionWithRetry(
connection, connection,
wallet, wallet,

View File

@ -8,12 +8,12 @@ import {
Input, Input,
Statistic, Statistic,
Slider, Slider,
Progress,
Spin, Spin,
InputNumber, InputNumber,
Form, Form,
Typography, Typography,
Space, Space,
Card,
} from 'antd'; } from 'antd';
import { ArtCard } from './../../components/ArtCard'; import { ArtCard } from './../../components/ArtCard';
import { UserSearch, UserValue } from './../../components/UserSearch'; import { UserSearch, UserValue } from './../../components/UserSearch';
@ -41,7 +41,7 @@ import { useHistory, useParams } from 'react-router-dom';
import { cleanName, getLast } from '../../utils/utils'; import { cleanName, getLast } from '../../utils/utils';
import { AmountLabel } from '../../components/AmountLabel'; import { AmountLabel } from '../../components/AmountLabel';
import useWindowDimensions from '../../utils/layout'; import useWindowDimensions from '../../utils/layout';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; import { LoadingOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
const { Step } = Steps; const { Step } = Steps;
const { Dragger } = Upload; const { Dragger } = Upload;
@ -55,6 +55,7 @@ export const ArtCreateView = () => {
const { step_param }: { step_param: string } = useParams(); const { step_param }: { step_param: string } = useParams();
const history = useHistory(); const history = useHistory();
const { width } = useWindowDimensions(); const { width } = useWindowDimensions();
const [nftCreateProgress, setNFTcreateProgress] = useState<number>(0)
const [step, setStep] = useState<number>(0); const [step, setStep] = useState<number>(0);
const [stepsVisible, setStepsVisible] = useState<boolean>(true); const [stepsVisible, setStepsVisible] = useState<boolean>(true);
@ -118,6 +119,7 @@ export const ArtCreateView = () => {
env, env,
files, files,
metadata, metadata,
setNFTcreateProgress,
attributes.properties?.maxSupply, attributes.properties?.maxSupply,
); );
@ -205,6 +207,7 @@ export const ArtCreateView = () => {
<WaitingStep <WaitingStep
mint={mint} mint={mint}
minting={isMinting} minting={isMinting}
step={nftCreateProgress}
confirm={() => gotoStep(6)} confirm={() => gotoStep(6)}
/> />
)} )}
@ -1139,6 +1142,7 @@ const WaitingStep = (props: {
mint: Function; mint: Function;
minting: boolean; minting: boolean;
confirm: Function; confirm: Function;
step: number;
}) => { }) => {
useEffect(() => { useEffect(() => {
const func = async () => { const func = async () => {
@ -1148,6 +1152,13 @@ const WaitingStep = (props: {
func(); func();
}, []); }, []);
const setIconForStep = (currentStep: number, componentStep) => {
if (currentStep === componentStep) {
return <LoadingOutlined />
}
return null;
}
return ( return (
<div <div
style={{ style={{
@ -1158,10 +1169,19 @@ const WaitingStep = (props: {
}} }}
> >
<Spin size="large" /> <Spin size="large" />
<div className="waiting-title"> <Card>
Your creation is being uploaded to the decentralized web... <Steps direction="vertical" current={props.step}>
</div> <Step title="Minting" description="Starting Mint Process" icon={setIconForStep(props.step, 0)} />
<div className="waiting-subtitle">This can take up to 1 minute.</div> <Step title="Preparing Assets" icon={setIconForStep(props.step, 1)} />
<Step title="Signing Metadata Transaction" description="Approve the transaction from your wallet" icon={setIconForStep(props.step, 2)} />
<Step title="Sending Transaction to Solana" description="This will take a few seconds." icon={setIconForStep(props.step, 3)} />
<Step title="Waiting for Initial Confirmation" icon={setIconForStep(props.step, 4)} />
<Step title="Waiting for Final Confirmation" icon={setIconForStep(props.step, 5)} />
<Step title="Uploading to Arweave" icon={setIconForStep(props.step, 6)} />
<Step title="Updating Metadata" icon={setIconForStep(props.step, 7)} />
<Step title="Signing Token Transaction" description="Approve the final transaction from your wallet" icon={setIconForStep(props.step, 8)} />
</Steps>
</Card>
</div> </div>
); );
}; };
@ -1188,6 +1208,7 @@ const Congrats = (props: {
}; };
if (props.alert) { if (props.alert) {
// TODO - properly reset this components state on error
return ( return (
<> <>
<div className="waiting-title">Sorry, there was an error!</div> <div className="waiting-title">Sorry, there was an error!</div>