From 97bb60b3ff913e73601b00ecdbf2de18035f17f4 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Wed, 10 Apr 2024 18:48:56 +0300 Subject: [PATCH] Add option to instantiate whitelist merkletree --- pages/contracts/whitelist/instantiate.tsx | 134 ++++++++++++++++++---- 1 file changed, 113 insertions(+), 21 deletions(-) diff --git a/pages/contracts/whitelist/instantiate.tsx b/pages/contracts/whitelist/instantiate.tsx index 316afd2..2af92e2 100644 --- a/pages/contracts/whitelist/instantiate.tsx +++ b/pages/contracts/whitelist/instantiate.tsx @@ -1,6 +1,7 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable no-nested-ternary */ import { coin } from '@cosmjs/proto-signing' +import axios from 'axios' import { Alert } from 'components/Alert' import { Button } from 'components/Button' import { Conditional } from 'components/Conditional' @@ -34,17 +35,22 @@ import { withMetadata } from 'utils/layout' import { links } from 'utils/links' import { useWallet } from 'utils/wallet' -import { WHITELIST_CODE_ID, WHITELIST_FLEX_CODE_ID } from '../../../utils/constants' +import { + WHITELIST_CODE_ID, + WHITELIST_FLEX_CODE_ID, + WHITELIST_MERKLE_TREE_API_URL, + WHITELIST_MERKLE_TREE_CODE_ID, +} from '../../../utils/constants' const WhitelistInstantiatePage: NextPage = () => { const wallet = useWallet() - const { whitelist: contract } = useContracts() + const { whitelist: contract, whitelistMerkleTree: whitelistMerkleTreeContract } = useContracts() const { timezone } = useGlobalSettings() const [startDate, setStartDate] = useState(undefined) const [endDate, setEndDate] = useState(undefined) const [adminsMutable, setAdminsMutable] = useState(true) - const [whitelistType, setWhitelistType] = useState<'standard' | 'flex'>('standard') + const [whitelistType, setWhitelistType] = useState<'standard' | 'flex' | 'merkletree'>('standard') const [whitelistStandardArray, setWhitelistStandardArray] = useState([]) const [whitelistFlexArray, setWhitelistFlexArray] = useState([]) @@ -85,12 +91,16 @@ const WhitelistInstantiatePage: NextPage = () => { const addressListState = useAddressListState() const { data, isLoading, mutate } = useMutation( - async (event: FormEvent): Promise => { + async (event: FormEvent): Promise => { event.preventDefault() if (!contract) { throw new Error('Smart contract connection failed') } + if (!whitelistMerkleTreeContract && whitelistType === 'merkletree') { + throw new Error('Smart contract connection failed') + } + if (!startDate) { throw new Error('Start date is required') } @@ -132,19 +142,79 @@ const WhitelistInstantiatePage: NextPage = () => { admins_mutable: adminsMutable, } - return toast.promise( - contract.instantiate( - whitelistType === 'standard' ? WHITELIST_CODE_ID : WHITELIST_FLEX_CODE_ID, - whitelistType === 'standard' ? standardMsg : flexMsg, - whitelistType === 'standard' ? 'Stargaze Whitelist Contract' : 'Stargaze Whitelist Flex Contract', - wallet.address, - ), - { - loading: 'Instantiating contract...', - error: 'Instantiation failed!', - success: 'Instantiation success!', - }, - ) + if (whitelistType !== 'merkletree') { + return toast.promise( + contract.instantiate( + whitelistType === 'standard' ? WHITELIST_CODE_ID : WHITELIST_FLEX_CODE_ID, + whitelistType === 'standard' ? standardMsg : flexMsg, + whitelistType === 'standard' ? 'Stargaze Whitelist Contract' : 'Stargaze Whitelist Flex Contract', + wallet.address, + ), + { + loading: 'Instantiating contract...', + error: 'Instantiation failed!', + success: 'Instantiation success!', + }, + ) + } else if (whitelistType === 'merkletree') { + const members = whitelistStandardArray + const membersCsv = members.join('\n') + const membersBlob = new Blob([membersCsv], { type: 'text/csv' }) + const membersFile = new File([membersBlob], 'members.csv', { type: 'text/csv' }) + const formData = new FormData() + formData.append('whitelist', membersFile) + const response = await toast + .promise( + axios.post(`${WHITELIST_MERKLE_TREE_API_URL}/create_whitelist`, formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }), + { + loading: 'Fetching merkle root hash...', + success: 'Merkle root fetched successfully.', + error: 'Error fetching root hash from Whitelist Merkle Tree API.', + }, + ) + .catch((error) => { + console.log('error', error) + throw new Error('Whitelist instantiation failed.') + }) + + const rootHash = response.data.root_hash + console.log('rootHash', rootHash) + + const merkleTreeMsg = { + merkle_root: rootHash, + merkle_tree_uri: null, + start_time: (startDate.getTime() * 1_000_000).toString(), + end_time: (endDate.getTime() * 1_000_000).toString(), + mint_price: coin(String(Number(unitPriceState.value) * 1000000), selectedMintToken?.denom || 'ustars'), + per_address_limit: perAddressLimitState.value, + admins: [ + ...new Set( + addressListState.values + .map((a) => a.address.trim()) + .filter((address) => address !== '' && isValidAddress(address.trim()) && address.startsWith('stars')), + ), + ] || [wallet.address], + admins_mutable: adminsMutable, + } + + return toast.promise( + whitelistMerkleTreeContract?.instantiate( + WHITELIST_MERKLE_TREE_CODE_ID, + merkleTreeMsg, + 'Stargaze Whitelist Merkle Tree Contract', + wallet.address, + ) as Promise, + { + loading: 'Instantiating contract...', + error: 'Instantiation failed!', + success: 'Instantiation success!', + }, + ) + } }, { onError: (error) => { @@ -176,7 +246,7 @@ const WhitelistInstantiatePage: NextPage = () => { /> -
+
{ Whitelist Flex
+ +
+ { + setWhitelistType('merkletree') + }} + type="radio" + value="merkletree" + /> + +
@@ -251,7 +341,7 @@ const WhitelistInstantiatePage: NextPage = () => {
- + 0}> @@ -283,8 +373,10 @@ const WhitelistInstantiatePage: NextPage = () => { - - + + + +