import { Alert, Button, Flex, Input, VStack } from "@chakra-ui/react"; import { yupResolver } from "@hookform/resolvers/yup"; import { DataV2 } from "@metaplex-foundation/mpl-token-metadata"; import { NATIVE_MINT } from "@solana/spl-token"; import { useWallet } from "@solana/wallet-adapter-react"; import { useWalletModal } from "@solana/wallet-adapter-react-ui"; import { Keypair, PublicKey } from "@solana/web3.js"; import { MarketplaceSdk } from "@strata-foundation/marketplace-sdk"; import { useMintTokenRef, usePrimaryClaimedTokenRef, useProvider, usePublicKey, } from "@strata-foundation/react"; import React, { useEffect } from "react"; import { useAsyncCallback } from "react-async-hook"; import { DefaultValues, FormProvider, useForm } from "react-hook-form"; import * as yup from "yup"; import { useMarketplaceSdk } from "../../contexts/marketplaceSdkContext"; import { FormControlWithError } from "./FormControlWithError"; import { MintSelect } from "./MintSelect"; import { Recipient } from "./Recipient"; import { IMetadataFormProps, TokenMetadataInputs } from "./TokenMetadataInputs"; interface IBountyFormProps extends IMetadataFormProps { mint: string; shortName: string; contact: string; discussion: string; authority: string; } const validationSchema = yup.object({ mint: yup.string().required(), image: yup.mixed(), name: yup.string().required().min(2), description: yup.string(), shortName: yup.string().min(2).max(10), contact: yup.string(), discussion: yup.string(), authority: yup.string().required(), }); async function createBounty( marketplaceSdk: MarketplaceSdk, values: IBountyFormProps ): Promise { const mint = new PublicKey(values.mint); const authority = new PublicKey(values.authority); const targetMintKeypair = Keypair.generate(); const uri = await marketplaceSdk.tokenMetadataSdk.uploadMetadata({ provider: values.provider, name: values.name, symbol: values.shortName, description: values.description, image: values.image, mint: targetMintKeypair.publicKey, attributes: MarketplaceSdk.bountyAttributes({ mint, discussion: values.discussion, contact: values.contact, }), }); const { targetMint } = await marketplaceSdk.createBounty({ targetMintKeypair, authority, metadataUpdateAuthority: marketplaceSdk.provider.wallet.publicKey, metadata: new DataV2({ // Max name len 32 name: values.name.substring(0, 32), symbol: values.shortName.substring(0, 10), uri, sellerFeeBasisPoints: 0, creators: null, collection: null, uses: null, }), baseMint: mint, }); return targetMint; } export const BountyForm = ({ defaultValues = {}, onComplete, hide = new Set(), }: { defaultValues?: DefaultValues; onComplete?: (mintKey: PublicKey) => void; hide?: Set; }) => { const formProps = useForm({ resolver: yupResolver(validationSchema), defaultValues, }); const { register, handleSubmit, watch, setValue, formState: { errors, isSubmitting }, } = formProps; const { publicKey, connected } = useWallet(); const { visible, setVisible } = useWalletModal(); const { info: tokenRef } = usePrimaryClaimedTokenRef(publicKey); const { awaitingApproval } = useProvider(); const { execute, loading, error } = useAsyncCallback(createBounty); const { marketplaceSdk } = useMarketplaceSdk(); const { authority, mint } = watch(); const mintKey = usePublicKey(mint); const { info: mintTokenRef } = useMintTokenRef(mintKey); // Social tokens should default bounties to the owner of the social token // as the authority. This is generally better because if the owner acts in // bad faith, they'll collapse the value of their own token. Vs a fan who can // easily not give money to the creator useEffect(() => { if (!authority && mintTokenRef) { const owner = mintTokenRef.owner as PublicKey | undefined; if (owner) { setValue("authority", owner.toBase58()); } else { setValue("authority", mintTokenRef.publicKey.toBase58()); } } }, [mintTokenRef, authority, setValue]); const onSubmit = async (values: IBountyFormProps) => { const mintKey = await execute(marketplaceSdk!, values); onComplete && onComplete(mintKey); }; const authorityRegister = register("authority"); return ( {!connected && ( )}
{!hide.has("mint") && ( {tokenRef && ( )} setValue("mint", s)} /> )} {!hide.has("authority") && ( {publicKey && ( )} )} {!hide.has("contact") && ( )} {!hide.has("discussion") && ( )} {error && {error.toString()}}
); };