diff --git a/src/pages/Fox/components/FoxWifHat.tsx b/src/pages/Fox/components/FoxWifHat.tsx index 2a8fc6e40e3..f45f79218dc 100644 --- a/src/pages/Fox/components/FoxWifHat.tsx +++ b/src/pages/Fox/components/FoxWifHat.tsx @@ -1,25 +1,74 @@ import { Box, Container, Heading, Image, useColorModeValue } from '@chakra-ui/react' -import { foxAssetId } from '@shapeshiftoss/caip' -import { useCallback } from 'react' +import type { AccountId } from '@shapeshiftoss/caip' +import { foxAssetId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip' +import { useCallback, useMemo, useState } from 'react' import { useTranslate } from 'react-polyglot' import FoxWifHatIcon from 'assets/foxwifhat-logo.png' import { Text } from 'components/Text' import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag' +import { selectAccountIdsByChainId } from 'state/slices/selectors' +import { useAppSelector } from 'state/store' +import { useGetFoxWifHatClaims } from '../hooks/useGetFoxWifHatClaims' +import { FoxWifHatClaimModal } from './FoxWifHatClaimModal' import { FoxWifHatClaimRow } from './FoxWifHatClaimRow' // @TODO: replace with proper foxwifhat asset id -const foxWifHatAssetId = foxAssetId +export const foxWifHatAssetId = foxAssetId export const FoxWifHat = () => { const translate = useTranslate() const isFoxWifHatEnabled = useFeatureFlag('FoxPageFoxWifHatSection') const containerBackground = useColorModeValue('blackAlpha.50', 'whiteAlpha.50') + const accountIdsByChainId = useAppSelector(selectAccountIdsByChainId) + const [isClaimModalOpened, setIsClaimModalOpened] = useState(false) + const [claimAccountId, setClaimAccountId] = useState() - const handleClaim = useCallback(() => { - // eslint-disable-next-line no-console - console.log('Claim') - }, []) + const getFoxWifHatClaimsQuery = useGetFoxWifHatClaims() + + const handleClaimModalClose = useCallback(() => { + setClaimAccountId(undefined) + setIsClaimModalOpened(false) + }, [setClaimAccountId, setIsClaimModalOpened]) + + const handleClaimModalOpen = useCallback( + (accountId: AccountId) => { + setClaimAccountId(accountId) + setIsClaimModalOpened(true) + }, + [setClaimAccountId, setIsClaimModalOpened], + ) + + const claimRows = useMemo(() => { + const accountIds = accountIdsByChainId[fromAssetId(foxWifHatAssetId).chainId] + + if (getFoxWifHatClaimsQuery.isLoading || !getFoxWifHatClaimsQuery.data) return null + + return Object.entries(getFoxWifHatClaimsQuery.data.claims).map(([address, claim]) => { + const accountId = accountIds?.find( + accountId => fromAccountId(accountId).account === address.toLowerCase(), + ) + + if (!accountId) return null + + return ( + handleClaimModalOpen(accountId)} + /> + ) + }) + }, [ + handleClaimModalOpen, + accountIdsByChainId, + getFoxWifHatClaimsQuery.data, + getFoxWifHatClaimsQuery.isLoading, + ]) if (!isFoxWifHatEnabled) return null @@ -35,27 +84,18 @@ export const FoxWifHat = () => { - - + {claimRows} + + ) } diff --git a/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaim.tsx b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaim.tsx new file mode 100644 index 00000000000..a96c1146f71 --- /dev/null +++ b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaim.tsx @@ -0,0 +1,95 @@ +import { AnimatePresence } from 'framer-motion' +import { lazy, Suspense, useCallback, useState } from 'react' +import { MemoryRouter, Route, Switch, useLocation } from 'react-router' +import { makeSuspenseful } from 'utils/makeSuspenseful' + +import type { FoxWifHatClaimRouteProps } from './types' +import { FoxWifHatClaimRoutePaths } from './types' + +const suspenseFallback =
Loading...
+ +const defaultBoxSpinnerStyle = { + height: '500px', +} + +const FoxWifHatClaimConfirm = makeSuspenseful( + lazy(() => + import('./FoxWifHatClaimConfirm').then(({ FoxWifHatClaimConfirm }) => ({ + default: FoxWifHatClaimConfirm, + })), + ), + defaultBoxSpinnerStyle, +) + +const FoxWifHatClaimStatus = makeSuspenseful( + lazy(() => + import('./FoxWifHatClaimStatus').then(({ FoxWifHatClaimStatus }) => ({ + default: FoxWifHatClaimStatus, + })), + ), + defaultBoxSpinnerStyle, +) + +const FoxWifHatClaimEntries = [FoxWifHatClaimRoutePaths.Confirm, FoxWifHatClaimRoutePaths.Status] + +export const FoxWifHatClaim: React.FC = ({ accountId }) => { + return ( + + + + ) +} + +export const FoxWifHatClaimRoutes: React.FC = ({ accountId }) => { + const location = useLocation() + + const [claimTxid, setClaimTxid] = useState() + + // @TODO: implement tx confirmed + const handleTxConfirmed = useCallback(async () => { + await new Promise(resolve => setTimeout(resolve, 1000)) + console.log('tx confirmed') + }, []) + + const renderClaimConfirm = useCallback(() => { + return ( + + ) + }, [claimTxid, accountId]) + + const renderClaimStatus = useCallback(() => { + if (!claimTxid) return null + + return ( + + ) + }, [claimTxid, handleTxConfirmed, accountId]) + + return ( + + + + + + + + + ) +} diff --git a/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimConfirm.tsx b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimConfirm.tsx new file mode 100644 index 00000000000..06e1713230c --- /dev/null +++ b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimConfirm.tsx @@ -0,0 +1,242 @@ +import { + Button, + Card, + CardBody, + CardFooter, + CardHeader, + Flex, + Skeleton, + Stack, +} from '@chakra-ui/react' +import type { AccountId } from '@shapeshiftoss/caip' +import { fromAccountId } from '@shapeshiftoss/caip' +import { CONTRACT_INTERACTION } from '@shapeshiftoss/chain-adapters' +import { useMutation } from '@tanstack/react-query' +import type { FC } from 'react' +import { useCallback, useMemo } from 'react' +import { useTranslate } from 'react-polyglot' +import { useHistory } from 'react-router' +import { Amount } from 'components/Amount/Amount' +import { AssetIcon } from 'components/AssetIcon' +import type { RowProps } from 'components/Row/Row' +import { Row } from 'components/Row/Row' +import { SlideTransition } from 'components/SlideTransition' +import { Timeline, TimelineItem } from 'components/Timeline/Timeline' +import { useEvmFees } from 'hooks/queries/useEvmFees' +import { useWallet } from 'hooks/useWallet/useWallet' +import { fromBaseUnit } from 'lib/math' +import { firstFourLastFour } from 'lib/utils' +import { + assertGetEvmChainAdapter, + buildAndBroadcast, + createBuildCustomTxInput, +} from 'lib/utils/evm' +import { FOX_WIF_HAT_MERKLE_DISTRIBUTOR_CONTRACT } from 'pages/Fox/constant' +import { useGetFoxWifHatClaims } from 'pages/Fox/hooks/useGetFoxWifHatClaims' +import { + selectAccountNumberByAccountId, + selectAssetById, + selectTxById, +} from 'state/slices/selectors' +import { serializeTxIndex } from 'state/slices/txHistorySlice/utils' +import { useAppSelector } from 'state/store' + +import { foxWifHatAssetId } from '../FoxWifHat' +import { FoxWifHatClaimRoutePaths } from './types' + +type FoxWifHatClaimConfirmProps = { + setClaimTxid: (txId: string) => void + claimTxid: string | undefined + accountId: AccountId +} + +const CustomRow: React.FC = props => + +export const FoxWifHatClaimConfirm: FC = ({ + accountId, + claimTxid, + setClaimTxid, +}) => { + const history = useHistory() + const translate = useTranslate() + const wallet = useWallet().state.wallet + const accountNumber = useAppSelector(state => + selectAccountNumberByAccountId(state, { accountId }), + ) + const foxWifHatAsset = useAppSelector(state => selectAssetById(state, foxWifHatAssetId)) + const getFoxWifHatClaimsQuery = useGetFoxWifHatClaims() + + console.log({ getFoxWifHatClaimsQuery }) + + const claimQuote = useMemo(() => { + const claim = getFoxWifHatClaimsQuery.data?.claims[fromAccountId(accountId).account] + if (!claim) return null + + return claim + }, [getFoxWifHatClaimsQuery.data, accountId]) + + const amountCryptoPrecision = useMemo(() => { + if (!foxWifHatAsset) return + if (!claimQuote) return + + return fromBaseUnit(claimQuote.amount, foxWifHatAsset.precision) + }, [claimQuote, foxWifHatAsset]) + + const { + mutateAsync: handleClaim, + isIdle: isClaimMutationIdle, + isPending: isClaimMutationPending, + isSuccess: isClaimMutationSuccess, + } = useMutation({ + mutationFn: async () => { + if (!wallet || accountNumber === undefined) return + + const adapter = assertGetEvmChainAdapter(fromAccountId(accountId).chainId) + + const buildCustomTxInput = await createBuildCustomTxInput({ + accountNumber, + from: fromAccountId(accountId).account, + adapter, + // @TODO: add proper data + data: '0x', + value: '0', + to: FOX_WIF_HAT_MERKLE_DISTRIBUTOR_CONTRACT, + wallet, + }) + + const txId = await buildAndBroadcast({ + adapter, + buildCustomTxInput, + receiverAddress: CONTRACT_INTERACTION, // no receiver for this contract call + }) + + return txId + }, + onSuccess: (txId: string | undefined) => { + if (!txId) return + + setClaimTxid(txId) + }, + }) + + const isGetClaimFeesEnabled = useMemo(() => Boolean(isClaimMutationIdle), [isClaimMutationIdle]) + + const claimFeesQueryInput = useMemo( + () => ({ + to: FOX_WIF_HAT_MERKLE_DISTRIBUTOR_CONTRACT, + from: fromAccountId(accountId).account, + chainId: fromAccountId(accountId).chainId, + accountNumber, + data: '0x', + value: '0', + }), + [accountNumber, accountId], + ) + + const { + data: claimFees, + isLoading: isClaimFeesLoading, + isSuccess: isClaimFeesSuccess, + } = useEvmFees({ + ...claimFeesQueryInput, + enabled: isGetClaimFeesEnabled, + staleTime: 30_000, + // Ensures fees are refetched at an interval, including when the app is in the background + refetchIntervalInBackground: true, + refetchInterval: isGetClaimFeesEnabled ? 15_000 : false, + }) + + const serializedClaimTxIndex = useMemo(() => { + if (!(claimTxid && fromAccountId(accountId).account && accountId)) return '' + return serializeTxIndex(accountId, claimTxid, fromAccountId(accountId).account) + }, [claimTxid, accountId]) + + const claimCard = useMemo(() => { + return ( + + + + + + + ) + }, [amountCryptoPrecision, foxWifHatAsset]) + + const handleSubmit = useCallback(async () => { + const txHash = await handleClaim() + if (!txHash) return + history.push(FoxWifHatClaimRoutePaths.Status) + }, [handleClaim, history]) + + const claimTx = useAppSelector(gs => selectTxById(gs, serializedClaimTxIndex)) + + const isClaimTxPending = useMemo( + () => isClaimMutationPending || (isClaimMutationSuccess && !claimTx), + [claimTx, isClaimMutationPending, isClaimMutationSuccess], + ) + + return ( + + + {translate('common.claim')} + + + + + {claimCard} + + + + {translate('RFOX.claimReceiveAddress')} + {firstFourLastFour(fromAccountId(accountId).account)} + + + + + {translate('RFOX.networkFee')} + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimStatus.tsx b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimStatus.tsx new file mode 100644 index 00000000000..fdd1ce4ea7b --- /dev/null +++ b/src/pages/Fox/components/FoxWifHatClaim/FoxWifHatClaimStatus.tsx @@ -0,0 +1,151 @@ +import { CheckCircleIcon, WarningIcon } from '@chakra-ui/icons' +import type { AccountId } from '@shapeshiftoss/caip' +import { fromAccountId } from '@shapeshiftoss/caip' +import { TxStatus } from '@shapeshiftoss/unchained-client' +import type { InterpolationOptions } from 'node-polyglot' +import React, { useMemo } from 'react' +import { CircularProgress } from 'components/CircularProgress/CircularProgress' +import type { TextPropTypes } from 'components/Text/Text' +import { useSafeTxQuery } from 'hooks/queries/useSafeTx' +import { useTxStatus } from 'hooks/useTxStatus/useTxStatus' +import { bnOrZero } from 'lib/bignumber/bignumber' +import { getTxLink } from 'lib/getTxLink' +import { fromBaseUnit } from 'lib/math' +import { useGetFoxWifHatClaims } from 'pages/Fox/hooks/useGetFoxWifHatClaims' +import { SharedStatus } from 'pages/RFOX/components/Shared/SharedStatus' +import { selectAssetById } from 'state/slices/selectors' +import { useAppSelector } from 'state/store' + +import { foxWifHatAssetId } from '../FoxWifHat' + +type BodyContent = { + key: TxStatus + title: string | [string, InterpolationOptions] + body: TextPropTypes['translation'] + element: JSX.Element +} + +type FoxWifHatClaimStatusProps = { + accountId: AccountId + txId: string + setClaimTxid: (txId: string) => void + onTxConfirmed: () => Promise +} + +export const FoxWifHatClaimStatus: React.FC = ({ + accountId, + txId, + setClaimTxid, + onTxConfirmed: handleTxConfirmed, +}) => { + const getFoxWifHatClaimsQuery = useGetFoxWifHatClaims() + + const claimQuote = useMemo(() => { + const claim = getFoxWifHatClaimsQuery.data?.claims[fromAccountId(accountId).account] + if (!claim) return null + + return claim + }, [getFoxWifHatClaimsQuery.data, accountId]) + + const claimAsset = useAppSelector(state => selectAssetById(state, foxWifHatAssetId)) + const claimAmountCryptoPrecision = useMemo( + () => fromBaseUnit(claimQuote?.amount ?? '0', claimAsset?.precision ?? 0), + [claimQuote?.amount, claimAsset?.precision], + ) + + const txStatus = useTxStatus({ + accountId, + txHash: txId, + onTxStatusConfirmed: handleTxConfirmed, + }) + + const { data: maybeSafeTx } = useSafeTxQuery({ + maybeSafeTxHash: txId ?? undefined, + accountId, + }) + + const bodyContent: BodyContent | null = useMemo(() => { + if (!claimAsset) return null + + if (maybeSafeTx?.isQueuedSafeTx) { + return { + key: TxStatus.Pending, + title: [ + 'common.safeProposalQueued', + { + currentConfirmations: maybeSafeTx?.transaction?.confirmations?.length, + confirmationsRequired: maybeSafeTx?.transaction?.confirmationsRequired, + }, + ], + body: [ + 'RFOX.claimPending', + { amount: bnOrZero(claimAmountCryptoPrecision).toFixed(8), symbol: claimAsset.symbol }, + ], + element: , + } + } + + if (maybeSafeTx?.isExecutedSafeTx && maybeSafeTx?.transaction?.transactionHash) { + setClaimTxid(maybeSafeTx.transaction.transactionHash) + } + + switch (txStatus) { + case undefined: + case TxStatus.Pending: + return { + key: TxStatus.Pending, + title: 'pools.waitingForConfirmation', + body: [ + 'RFOX.claimPending', + { amount: bnOrZero(claimAmountCryptoPrecision).toFixed(8), symbol: claimAsset.symbol }, + ], + element: , + } + case TxStatus.Confirmed: + return { + key: TxStatus.Confirmed, + title: 'common.success', + body: [ + 'RFOX.claimSuccess', + { + amount: bnOrZero(claimAmountCryptoPrecision).toFixed(8), + symbol: claimAsset.symbol, + }, + ], + element: , + } + case TxStatus.Failed: + return { + key: TxStatus.Failed, + title: 'common.somethingWentWrong', + body: 'common.somethingWentWrongBody', + element: , + } + default: + return null + } + }, [ + claimAsset, + maybeSafeTx?.isQueuedSafeTx, + maybeSafeTx?.isExecutedSafeTx, + maybeSafeTx?.transaction?.confirmations?.length, + maybeSafeTx?.transaction?.confirmationsRequired, + maybeSafeTx?.transaction?.transactionHash, + txStatus, + claimAmountCryptoPrecision, + setClaimTxid, + ]) + + const txLink = useMemo( + () => + getTxLink({ + txId, + defaultExplorerBaseUrl: claimAsset?.explorerTxLink ?? '', + accountId, + maybeSafeTx, + }), + [accountId, claimAsset?.explorerTxLink, maybeSafeTx, txId], + ) + + return +} diff --git a/src/pages/Fox/components/FoxWifHatClaim/types.ts b/src/pages/Fox/components/FoxWifHatClaim/types.ts new file mode 100644 index 00000000000..46b608fdfe7 --- /dev/null +++ b/src/pages/Fox/components/FoxWifHatClaim/types.ts @@ -0,0 +1,10 @@ +import type { AccountId } from '@shapeshiftoss/caip' + +export enum FoxWifHatClaimRoutePaths { + Confirm = '/claim/confirm', + Status = '/claim/status', +} + +export type FoxWifHatClaimRouteProps = { + accountId: AccountId +} diff --git a/src/pages/Fox/components/FoxWifHatClaimModal.tsx b/src/pages/Fox/components/FoxWifHatClaimModal.tsx new file mode 100644 index 00000000000..5435e67189d --- /dev/null +++ b/src/pages/Fox/components/FoxWifHatClaimModal.tsx @@ -0,0 +1,32 @@ +import { Card, Modal, ModalContent, ModalOverlay } from '@chakra-ui/react' +import type { AccountId } from '@shapeshiftoss/caip' +import React from 'react' + +import { FoxWifHatClaim } from './FoxWifHatClaim/FoxWifHatClaim' + +type FoxWifHatClaimModalProps = { + isOpen: boolean + accountId?: AccountId + onClose: () => void +} + +const modalBorderRadius = { base: 0, md: '2xl' } + +export const FoxWifHatClaimModal: React.FC = ({ + isOpen = false, + onClose, + accountId, +}) => { + if (!accountId) return null + + return ( + + + + + + + + + ) +} diff --git a/src/pages/Fox/components/FoxWifHatClaimRow.tsx b/src/pages/Fox/components/FoxWifHatClaimRow.tsx index fde180389e1..e33dc2822c9 100644 --- a/src/pages/Fox/components/FoxWifHatClaimRow.tsx +++ b/src/pages/Fox/components/FoxWifHatClaimRow.tsx @@ -1,7 +1,7 @@ import type { StackDirection } from '@chakra-ui/react' import { Button, Flex, HStack, Stack, Text, useColorModeValue } from '@chakra-ui/react' import type { AssetId } from '@shapeshiftoss/caip' -import { fromAssetId } from '@shapeshiftoss/caip' +import { fromAccountId, fromAssetId } from '@shapeshiftoss/caip' import { useMemo } from 'react' import { useTranslate } from 'react-polyglot' import { Amount } from 'components/Amount/Amount' @@ -55,7 +55,7 @@ export const FoxWifHatClaimRow = ({ return accountIdsByChainId[fromAssetId(assetId).chainId]?.length ?? 0 }, [accountIdsByChainId, assetId]) - const amountCryptoHuman = useMemo(() => { + const amountCryptoPrecision = useMemo(() => { if (!foxWifHatAsset) return return fromBaseUnit(amountCryptoBaseUnit, foxWifHatAsset.precision) @@ -76,7 +76,7 @@ export const FoxWifHatClaimRow = ({ - {middleEllipsis(accountId)} + {middleEllipsis(fromAccountId(accountId).account)} {numberAccounts > 1 ? ( @@ -87,7 +87,7 @@ export const FoxWifHatClaimRow = ({ +} + +export const merkleData: MerkleData = { + merkleRoot: '0xae3c7f332242941da1989f26e7a1675f2be1adfa263fd6ab6960b42689a8bf20', + tokenTotal: '0x07695a92c20d6fe0000001', + claims: { + '0x64817998666D17521a3D2f03503Eba18d3038f7D': { + index: 0, + amount: '0x43c33c19375648000000', + proof: [ + '0x053096cad35db69b922218e3aab91b92f32ec8dd71a78a432885ffa58b106b65', + '0x0e10327c2918a54b54b557f22b58777a46a545cdc441012b170aa8e12c9c391a', + '0xf923e44255f5cabc99fcd0d5147c86b97dc1bf2d7160d37caa4cf851d286b516', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x6138a1F335f99c9881Cd02Ae17E495485EE5E3A7': { + index: 1, + amount: '0x1969368974c05b000000', + proof: [ + '0xa9725684967f1f0b068b732b7542fa75065ba918ebdde5b2e28280a572d71c8b', + '0x9b13bcc84bab67c2f81a417eceb850669e9d6e5726cdbc9a6d6dfc60e0d1d21c', + '0xc0ef3d84d05959658620659907a6771386ecddffadaebca9866fc73992b3fa00', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x000f93C30ec9faE4999CEEBA862002358fA369C2': { + index: 2, + amount: '0x043c33c1937564800000', + proof: [ + '0xb14da98ea8ef2eba548f9718a7904ef177aa76246b0f8f4ee926c0108c68b2fe', + '0x3226e5f367f5a355899a57bcf8c991f9852884941c512f7850ca4a14ef756c89', + ], + }, + '0x0016fa70346D4b7869ac9D89cEC6a0d7F2473F95': { + index: 3, + amount: '0x43c33c19375648000000', + proof: [ + '0x85bda7a31f826d53c2e474ac88a57df4e205a73888c8591245872bb6280e03b9', + '0x1e42d62035723f2db88c87e6a97303c8e2bc025052bcb1692522f36f290cf60b', + '0xbe1f3eec41888c9445697aa788459c1c9f1ed9e8d7a3aa0fae6de613048c9a96', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00196341fCe30A61c455dDa0973aE8c0471A224f': { + index: 4, + amount: '0x6e1d41a8f9ec35000000', + proof: [ + '0xc9e4a858d904d3bef4f0cb084c747c9ed7ed4500527019e16d8a2b4655e33809', + '0x21ffd6d795213694eccc4e82e71e58fb05c2675790d94b3ac5f8f515faaa8a4a', + '0xc0ef3d84d05959658620659907a6771386ecddffadaebca9866fc73992b3fa00', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x0023FabE1F42c5D0CEdD54087080240aC8E0a1eF': { + index: 5, + amount: '0x834a4470db372b800000', + proof: [ + '0x1a8046a3c5a0198c634b8465fbde1c7fe1376979a95a7af193db3f77dffded17', + '0xbb0533a4b049626872d50dd4a0eac863d6aa4f271300f2af428b6b4c11799117', + '0xf923e44255f5cabc99fcd0d5147c86b97dc1bf2d7160d37caa4cf851d286b516', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x002Ed704b63787be94C5962d06Ca2411d5a08269': { + index: 6, + amount: '0x1969368974c05b000000', + proof: [ + '0x461910556d85344194365f4cfc0ab8ca977e160c2eb7af82718f9edd52453d09', + '0x7d98e60b9437c9dd6117d5977e18c7b12a6d90c3a329060abc7adceabae490a1', + '0x01ef1f6fc11e5fd3bafadee844aff5408c14724de0f82180c620096eaf0f7bd5', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x0038d77a33e90a02405311C5CCf9c75f7c301901': { + index: 7, + amount: '0x2e963951560b51800000', + proof: [ + '0xd622a97a0e0ea86f502fedc8ac1fb313bf37bcc80ad40325fe60896a2e0799e2', + '0x125e6de0cc75edf4ab3f505835ed913a7be0cedb317d934143c07ea8a4a2992a', + '0xf9a0d029cd3a5fcc8ec7bad3f108bb04e8d3882577272950fc23f8cba3e4b653', + '0x3226e5f367f5a355899a57bcf8c991f9852884941c512f7850ca4a14ef756c89', + ], + }, + '0x003900c0291d5C3645f6DCBCCffDd3f534Af5ad5': { + index: 8, + amount: '0x065a4da25d3016c00000', + proof: [ + '0xe26bc23f94a297b6ba2bce5a7c5be1a1bd3a9c7d24ac952252fc4e46501b6204', + '0x125e6de0cc75edf4ab3f505835ed913a7be0cedb317d934143c07ea8a4a2992a', + '0xf9a0d029cd3a5fcc8ec7bad3f108bb04e8d3882577272950fc23f8cba3e4b653', + '0x3226e5f367f5a355899a57bcf8c991f9852884941c512f7850ca4a14ef756c89', + ], + }, + '0x00407b7448A3EceaaE2653d5cFA0B7e018b6d209': { + index: 9, + amount: '0x4e59bd7d27fbc3400000', + proof: [ + '0xe9d5e9ab4457c23bb13afe79658ffbe60505fc421ee421b36697c0d1ab72bb05', + '0x00d3e8df2a54ea50de4aed4ec4535ce1f4031472378eb697077a8ec86ff08497', + '0xf9a0d029cd3a5fcc8ec7bad3f108bb04e8d3882577272950fc23f8cba3e4b653', + '0x3226e5f367f5a355899a57bcf8c991f9852884941c512f7850ca4a14ef756c89', + ], + }, + '0x00424c56EB877010A7b7d05E487121E2201536ba': { + index: 10, + amount: '0x41a522386d9b95c00000', + proof: [ + '0x48a1eedb06a82c0ba76ee0147579ea1ca848a202335b23d90a9a0a990485cbb0', + '0x7d98e60b9437c9dd6117d5977e18c7b12a6d90c3a329060abc7adceabae490a1', + '0x01ef1f6fc11e5fd3bafadee844aff5408c14724de0f82180c620096eaf0f7bd5', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00432d7d34De0bF5a511c40576c320703797a9Df': { + index: 11, + amount: '0x4a1d89bb94865ec00000', + proof: [ + '0x4e7d6f8319112d076892a5325f62833d4777c5a081baef6f1f8d69dcbeb9249c', + '0xbade4357c3802d5d22f10941a3fdfabc73c05d8fc6b5da89f43f1a47fff6500a', + '0x01ef1f6fc11e5fd3bafadee844aff5408c14724de0f82180c620096eaf0f7bd5', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x004E6425cD81066D8C622F5763b5E30fa586f376': { + index: 12, + amount: '0x021e19e0c9bab2400000', + proof: [ + '0x892c106ea698c952c9f2a1a4517df480a9b37f5dd588c520de5e078b84c11661', + '0x1e42d62035723f2db88c87e6a97303c8e2bc025052bcb1692522f36f290cf60b', + '0xbe1f3eec41888c9445697aa788459c1c9f1ed9e8d7a3aa0fae6de613048c9a96', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00533e6967aEB11a3B172A0FcC491f433E750513': { + index: 13, + amount: '0x065a4da25d3016c00000', + proof: [ + '0x812591bfbb4eb1c386a909f6bd850587944d5853d2fa67067bd71c36d8f9769d', + '0x75e84c78e8a287f7b926310fb54b96a407e2cfbde710c27271913b8f2a7f6de1', + '0xbe1f3eec41888c9445697aa788459c1c9f1ed9e8d7a3aa0fae6de613048c9a96', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x0055284f884a257937896EF7153a5d9e7A162Be5': { + index: 14, + amount: '0x01178557e80443e9000000', + proof: [ + '0xf10cea16f288d7ff1c785f3d13809185c8d0f9123639384a31aef8392f4693f2', + '0x00d3e8df2a54ea50de4aed4ec4535ce1f4031472378eb697077a8ec86ff08497', + '0xf9a0d029cd3a5fcc8ec7bad3f108bb04e8d3882577272950fc23f8cba3e4b653', + '0x3226e5f367f5a355899a57bcf8c991f9852884941c512f7850ca4a14ef756c89', + ], + }, + '0x005D55487f426f67e35fc61E6661DaBE8b988611': { + index: 15, + amount: '0x1969368974c05b000000', + proof: [ + '0x1b1c1793855a690a0269b8595aafb4537d70e993e7c258b5cf3c22c9da3d9d07', + '0xbb0533a4b049626872d50dd4a0eac863d6aa4f271300f2af428b6b4c11799117', + '0xf923e44255f5cabc99fcd0d5147c86b97dc1bf2d7160d37caa4cf851d286b516', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00654f35d114EefAFE5D1aC94C268Df8D01DAe2e': { + index: 16, + amount: '0x02b036da601a044b400000', + proof: [ + '0x7f345cc821ca0a88a60095a08c1b52ede441548d57df061da6422b45e90bd9c5', + '0x75e84c78e8a287f7b926310fb54b96a407e2cfbde710c27271913b8f2a7f6de1', + '0xbe1f3eec41888c9445697aa788459c1c9f1ed9e8d7a3aa0fae6de613048c9a96', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x0067B499e219dA1292FAb512B2ebA0C135B10f89': { + index: 17, + amount: '0x1b87506a3e7b0d400000', + proof: [ + '0x8994522bf410c8fc09f1562918856a3996a3bc25673f0f517cbca4cd8194d2b7', + '0x9b13bcc84bab67c2f81a417eceb850669e9d6e5726cdbc9a6d6dfc60e0d1d21c', + '0xc0ef3d84d05959658620659907a6771386ecddffadaebca9866fc73992b3fa00', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x006836b3EA29de548F75d9F07e2E7eAc5C1e797c': { + index: 18, + amount: '0x89a49213386742400000', + proof: [ + '0xd1437ec44c5907b0822754c3104525045b50d90e6465e9d2a2527c0efe1b671a', + '0x21ffd6d795213694eccc4e82e71e58fb05c2675790d94b3ac5f8f515faaa8a4a', + '0xc0ef3d84d05959658620659907a6771386ecddffadaebca9866fc73992b3fa00', + '0xeef5e6f9e523f2214e80cd72a6aab305700a0973d7f4681f9566a8b90a70b6cd', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00696174368368fb11B91a5cE8c6bE5C1766E628': { + index: 19, + amount: '0x021e19e0c9bab2400000', + proof: [ + '0x0e0d6eea5222af512ff421d8844344596807b6c41aee682027eadc148acfee87', + '0x0e10327c2918a54b54b557f22b58777a46a545cdc441012b170aa8e12c9c391a', + '0xf923e44255f5cabc99fcd0d5147c86b97dc1bf2d7160d37caa4cf851d286b516', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + '0x00709fc50f42763943309B4d0268b9651aC03510': { + index: 20, + amount: '0x1969368974c05b000001', + proof: [ + '0x76a04faaea4982fc242e88e0d7099917f9db5f777678658a9bb12c4c33c4d0e5', + '0xbade4357c3802d5d22f10941a3fdfabc73c05d8fc6b5da89f43f1a47fff6500a', + '0x01ef1f6fc11e5fd3bafadee844aff5408c14724de0f82180c620096eaf0f7bd5', + '0x634080667483b68a7af1f617bb95961d86e75800f2c20c578a760b4e258f9e6f', + '0xc9f3d8b718f15e5c9c78cef1e792d561c77aa115ab91263dbf789a5a53aee0cc', + ], + }, + }, +} diff --git a/src/pages/Fox/hooks/useGetFoxWifHatClaims.ts b/src/pages/Fox/hooks/useGetFoxWifHatClaims.ts new file mode 100644 index 00000000000..fc71860917f --- /dev/null +++ b/src/pages/Fox/hooks/useGetFoxWifHatClaims.ts @@ -0,0 +1,28 @@ +import { useQuery } from '@tanstack/react-query' +import { useCallback } from 'react' + +import { merkleData } from './foxwifhat-merkle' + +export const foxWifHatClaimsQueryKey = ['getFoxWifHatClaims'] + +export const useGetFoxWifHatClaims = () => { + const getFoxWifHatClaims = useCallback(async () => { + const addressLowercasedClaims = Object.entries(merkleData.claims).reduce( + (acc, [address, claim]) => { + acc[address.toLowerCase()] = claim + return acc + }, + {} as typeof merkleData.claims, + ) + + return await Promise.resolve({ + ...merkleData, + claims: addressLowercasedClaims, + }) + }, []) + + return useQuery({ + queryKey: foxWifHatClaimsQueryKey, + queryFn: getFoxWifHatClaims, + }) +}