diff --git a/contracts/royaltyRegistry/messages/execute.ts b/contracts/royaltyRegistry/messages/execute.ts index a4c018d..4d37d3b 100644 --- a/contracts/royaltyRegistry/messages/execute.ts +++ b/contracts/royaltyRegistry/messages/execute.ts @@ -52,35 +52,17 @@ export interface DispatchExecuteProps { type Select = T /** @see {@link RoyaltyRegistryInstance} */ -export type DispatchExecuteArgs = { +export interface DispatchExecuteArgs { contract: string + collection: string + protocol: string + recipient: string + share: number + shareDelta: number + decrement: boolean messages?: RoyaltyRegistryInstance -} & ( - | { type: Select<'initialize_collection_royalty'>; collection: string } - | { type: Select<'set_collection_royalty_default'>; collection: string; recipient: string; royalty: number } - | { - type: Select<'update_collection_royalty_default'> - collection: string - recipient: string - shareDelta: number - decrement: boolean - } - | { - type: Select<'set_collection_royalty_protocol'> - collection: string - protocol: string - recipient: string - royalty: number - } - | { - type: Select<'update_collection_royalty_protocol'> - collection: string - protocol: string - recipient: string - shareDelta: number - decrement: boolean - } -) + type: string | undefined +} export const dispatchExecute = async (args: DispatchExecuteArgs) => { const { messages } = args @@ -92,13 +74,13 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => { return messages.initializeCollectionRoyalty(args.collection) } case 'set_collection_royalty_default': { - return messages.setCollectionRoyaltyDefault(args.collection, args.recipient, args.royalty) + return messages.setCollectionRoyaltyDefault(args.collection, args.recipient, args.share) } case 'update_collection_royalty_default': { return messages.updateCollectionRoyaltyDefault(args.collection, args.recipient, args.shareDelta, args.decrement) } case 'set_collection_royalty_protocol': { - return messages.setCollectionRoyaltyProtocol(args.collection, args.protocol, args.recipient, args.royalty) + return messages.setCollectionRoyaltyProtocol(args.collection, args.protocol, args.recipient, args.share) } case 'update_collection_royalty_protocol': { return messages.updateCollectionRoyaltyProtocol( @@ -124,7 +106,7 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => { return messages(contract)?.initializeCollectionRoyalty(args.collection) } case 'set_collection_royalty_default': { - return messages(contract)?.setCollectionRoyaltyDefault(args.collection, args.recipient, args.royalty) + return messages(contract)?.setCollectionRoyaltyDefault(args.collection, args.recipient, args.share) } case 'update_collection_royalty_default': { return messages(contract)?.updateCollectionRoyaltyDefault( @@ -139,7 +121,7 @@ export const previewExecutePayload = (args: DispatchExecuteArgs) => { args.collection, args.protocol, args.recipient, - args.royalty, + args.share, ) } case 'update_collection_royalty_protocol': { diff --git a/pages/contracts/royaltyRegistry/execute.tsx b/pages/contracts/royaltyRegistry/execute.tsx new file mode 100644 index 0000000..0bd241c --- /dev/null +++ b/pages/contracts/royaltyRegistry/execute.tsx @@ -0,0 +1,177 @@ +import { Button } from 'components/Button' +import { Conditional } from 'components/Conditional' +import { ContractPageHeader } from 'components/ContractPageHeader' +import { ExecuteCombobox } from 'components/contracts/royaltyRegistry/ExecuteCombobox' +import { useExecuteComboboxState } from 'components/contracts/royaltyRegistry/ExecuteCombobox.hooks' +import { FormControl } from 'components/FormControl' +import { AddressInput } from 'components/forms/FormInput' +import { useInputState, useNumberInputState } from 'components/forms/FormInput.hooks' +import { JsonPreview } from 'components/JsonPreview' +import { LinkTabs } from 'components/LinkTabs' +import { royaltyRegistryLinkTabs } from 'components/LinkTabs.data' +import { TransactionHash } from 'components/TransactionHash' +import { useContracts } from 'contexts/contracts' +import { useWallet } from 'contexts/wallet' +import type { DispatchExecuteArgs } from 'contracts/royaltyRegistry/messages/execute' +import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/royaltyRegistry/messages/execute' +import type { NextPage } from 'next' +import { useRouter } from 'next/router' +import { NextSeo } from 'next-seo' +import type { FormEvent } from 'react' +import { useEffect, useMemo, useState } from 'react' +import { toast } from 'react-hot-toast' +import { FaArrowRight } from 'react-icons/fa' +import { useMutation } from 'react-query' +import { ROYALTY_REGISTRY_ADDRESS } from 'utils/constants' +import { withMetadata } from 'utils/layout' +import { links } from 'utils/links' + +const RoyaltyRegistryExecutePage: NextPage = () => { + const { royaltyRegistry: contract } = useContracts() + const wallet = useWallet() + + const [lastTx, setLastTx] = useState('') + + const comboboxState = useExecuteComboboxState() + const type = comboboxState.value?.id + + const contractState = useInputState({ + id: 'contract-address', + name: 'contract-address', + title: 'Royalty Registry Address', + subtitle: 'Address of the Royalty Registry contract', + defaultValue: ROYALTY_REGISTRY_ADDRESS, + }) + const contractAddress = contractState.value + + const collectionAddressState = useInputState({ + id: 'collection-address', + name: 'collection-address', + title: 'Collection Address', + subtitle: 'Address of the collection', + }) + + const protocolAddressState = useInputState({ + id: 'protocol-address', + name: 'protocol-address', + title: 'Protocol Address', + subtitle: 'Address of the protocol', + }) + + const recipientAddressState = useInputState({ + id: 'recipient-address', + name: 'recipient-address', + title: 'Recipient Address', + subtitle: 'Address of the recipient', + }) + + const shareState = useNumberInputState({ + id: 'share', + name: 'share', + title: 'Share', + subtitle: 'Share', + }) + + const shareDeltaState = useNumberInputState({ + id: 'share-delta', + name: 'share-delta', + title: 'Share Delta', + subtitle: 'Share delta', + }) + + const [decrement, setDecrement] = useState(false) + + const showRecipientAddress = isEitherType(type, [ + 'set_collection_royalty_default', + 'set_collection_royalty_protocol', + 'update_collection_royalty_default', + 'update_collection_royalty_protocol', + ]) + + const messages = useMemo(() => contract?.use(contractState.value), [contract, contractState.value]) + const payload: DispatchExecuteArgs = { + contract: contractState.value, + messages, + type, + collection: collectionAddressState.value, + protocol: protocolAddressState.value, + recipient: recipientAddressState.value, + share: shareState.value, + shareDelta: shareDeltaState.value, + decrement, + } + const { isLoading, mutate } = useMutation( + async (event: FormEvent) => { + event.preventDefault() + if (!type) { + throw new Error('Please select message type!') + } + if (!wallet.initialized) { + throw new Error('Please connect your wallet.') + } + const txHash = await toast.promise(dispatchExecute(payload), { + error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`, + loading: 'Executing message...', + success: (tx) => `Transaction ${tx} success!`, + }) + if (txHash) { + setLastTx(txHash) + } + }, + { + onError: (error) => { + toast.error(String(error), { style: { maxWidth: 'none' } }) + }, + }, + ) + + const router = useRouter() + + useEffect(() => { + if (contractAddress.length > 0) { + void router.replace({ query: { contractAddress } }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [contractAddress]) + useEffect(() => { + const initial = new URL(document.URL).searchParams.get('contractAddress') + if (initial && initial.length > 0) contractState.onChange(initial) + }, []) + + return ( +
+ + + + +
+
+ + + + + +
+
+
+ + + + +
+ + + +
+
+
+ ) +} + +export default withMetadata(RoyaltyRegistryExecutePage, { center: false }) diff --git a/pages/contracts/royaltyRegistry/index.tsx b/pages/contracts/royaltyRegistry/index.tsx new file mode 100644 index 0000000..6d40435 --- /dev/null +++ b/pages/contracts/royaltyRegistry/index.tsx @@ -0,0 +1 @@ +export { default } from './execute'