Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for fetching data in the dApp #914

Merged
merged 14 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
import React, { useCallback, useRef } from "react"
import { ONE_SEC_IN_MILLISECONDS, queryKeysFactory } from "#/constants"
import {
useActionFlowPause,
useActionFlowTokenAmount,
useAppDispatch,
useBitcoinBalance,
useCancelPromise,
useDepositBTCTransaction,
useInvalidateQueries,
useStakeFlowContext,
useVerifyDepositAddress,
} from "#/hooks"
import { usePostHogCapture } from "#/hooks/posthog/usePostHogCapture"
import { PostHogEvent } from "#/posthog/events"
import { setStatus, setTxHash } from "#/store/action-flow"
import { ONE_SEC_IN_MILLISECONDS } from "#/constants"
import { PROCESS_STATUSES } from "#/types"
import { eip1193, logPromiseFailure } from "#/utils"
import { useTimeout } from "@chakra-ui/react"
import { useMutation } from "@tanstack/react-query"
import WalletInteractionModal from "../WalletInteractionModal"

const { userKeys } = queryKeysFactory

export default function DepositBTCModal() {
const tokenAmount = useActionFlowTokenAmount()
const { btcAddress, depositReceipt, stake } = useStakeFlowContext()
const verifyDepositAddress = useVerifyDepositAddress()
const dispatch = useAppDispatch()
const { handlePause } = useActionFlowPause()
const handleBitcoinBalanceInvalidation = useInvalidateQueries({
queryKey: userKeys.balance(),
})
const { refetch: refetchBitcoinBalance } = useBitcoinBalance()
const { handleCapture, handleCaptureWithCause } = usePostHogCapture()

const sessionId = useRef(Math.random())
Expand All @@ -39,9 +35,9 @@ export default function DepositBTCModal() {
)

const onStakeBTCSuccess = useCallback(() => {
handleBitcoinBalanceInvalidation()
logPromiseFailure(refetchBitcoinBalance())
dispatch(setStatus(PROCESS_STATUSES.SUCCEEDED))
}, [dispatch, handleBitcoinBalanceInvalidation])
}, [dispatch, refetchBitcoinBalance])

const onError = useCallback(
(error: unknown) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,37 @@ import {
useActionFlowPause,
useActionFlowTokenAmount,
useAppDispatch,
useBitcoinPosition,
useCancelPromise,
useInvalidateQueries,
useModal,
useTimeout,
useTransactionDetails,
} from "#/hooks"
import { ACTION_FLOW_TYPES, PROCESS_STATUSES } from "#/types"
import { dateToUnixTimestamp, eip1193 } from "#/utils"
import { ACTION_FLOW_TYPES, Activity, PROCESS_STATUSES } from "#/types"
import { dateToUnixTimestamp, eip1193, logPromiseFailure } from "#/utils"
import { setStatus } from "#/store/action-flow"
import { useInitializeWithdraw } from "#/acre-react/hooks"
import { ONE_SEC_IN_MILLISECONDS, queryKeysFactory } from "#/constants"
import { activityInitialized } from "#/store/wallet"
import { useMutation } from "@tanstack/react-query"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { PostHogEvent } from "#/posthog/events"
import { usePostHogCapture } from "#/hooks/posthog/usePostHogCapture"
import BuildTransactionModal from "./BuildTransactionModal"
import WalletInteractionModal from "../WalletInteractionModal"

const { userKeys } = queryKeysFactory

type WithdrawalStatus = "building-data" | "built-data" | "signature"

export default function SignMessageModal() {
const [status, setWaitingStatus] = useState<WithdrawalStatus>("building-data")

const dispatch = useAppDispatch()
const queryClient = useQueryClient()
const tokenAmount = useActionFlowTokenAmount()
const amount = tokenAmount?.amount
const { closeModal } = useModal()
const { handlePause } = useActionFlowPause()
const initializeWithdraw = useInitializeWithdraw()
const handleBitcoinPositionInvalidation = useInvalidateQueries({
queryKey: userKeys.position(),
})
const { refetch: refetchBitcoinPosition } = useBitcoinPosition()

const sessionId = useRef(Math.random())
const { cancel, resolve, sessionIdToPromise } = useCancelPromise(
sessionId.current,
Expand All @@ -59,10 +56,10 @@ export default function SignMessageModal() {
}, [resolve])

const onSignMessageSuccess = useCallback(() => {
handleBitcoinPositionInvalidation()
logPromiseFailure(refetchBitcoinPosition())
dispatch(setStatus(PROCESS_STATUSES.SUCCEEDED))
handleCapture(PostHogEvent.WithdrawalSuccess)
}, [dispatch, handleBitcoinPositionInvalidation, handleCapture])
}, [dispatch, refetchBitcoinPosition, handleCapture])

const onSignMessageError = useCallback(
(error: unknown) => {
Expand Down Expand Up @@ -103,38 +100,44 @@ export default function SignMessageModal() {
onSignMessageCallback,
)

dispatch(
activityInitialized({
// Note that the withdraw id returned from the Acre SDK while fetching
// the withdrawals has the following pattern:
// `<redemptionKey>-<count>`. The redemption key returned during the
// withdrawal initialization does not contain the `-<count>` suffix
// because there may be delay between indexing the Acre subgraph and
// the time when a transaction was actually made and it's hard to get
// the exact number of the redemptions with the same key. Eg:
// - a user initialized a withdraw,
// - the Acre SDK is asking the subgraph for the number of withdrawals
// with the same redemption key,
// - the Acre subgraph may or may not be up to date with the chain and
// we are not sure if we should add +1 to the counter or the
// returned value already includes the requested withdraw from the
// first step. So we can't create the correct withdraw id.
// So here we set the id as a redemption key. Only one pending
// withdrawal can exist with the same redemption key, so when the user
// can initialize the next withdrawal with the same redemption key, we
// assume the dapp should already re-fetch all withdrawals with the
// correct IDs and move the `pending` redemption to `completed`
// section with the proper id.
id: redemptionKey,
type: "withdraw",
status: "pending",
// This is a requested amount. The amount of BTC received will be
// around: `amount - transactionFee.total`.
amount: amount - transactionFee.acre,
initializedAt: dateToUnixTimestamp(),
// The message is signed immediately after the initialization.
finalizedAt: dateToUnixTimestamp(),
}),
queryClient.setQueriesData(
{ queryKey: queryKeysFactory.userKeys.activities() },
(oldData: Activity[] | undefined) => {
const newActivity: Activity = {
// Note that the withdraw id returned from the Acre SDK while fetching
// the withdrawals has the following pattern:
// `<redemptionKey>-<count>`. The redemption key returned during the
// withdrawal initialization does not contain the `-<count>` suffix
// because there may be delay between indexing the Acre subgraph and
// the time when a transaction was actually made and it's hard to get
// the exact number of the redemptions with the same key. Eg:
// - a user initialized a withdraw,
// - the Acre SDK is asking the subgraph for the number of withdrawals
// with the same redemption key,
// - the Acre subgraph may or may not be up to date with the chain and
// we are not sure if we should add +1 to the counter or the
// returned value already includes the requested withdraw from the
// first step. So we can't create the correct withdraw id.
// So here we set the id as a redemption key. Only one pending
// withdrawal can exist with the same redemption key, so when the user
// can initialize the next withdrawal with the same redemption key, we
// assume the dapp should already re-fetch all withdrawals with the
// correct IDs and move the `pending` redemption to `completed`
// section with the proper id.
id: redemptionKey,
type: "withdraw",
status: "pending",
// This is a requested amount. The amount of BTC received will be
// around: `amount - transactionFee.total`.
amount: amount - transactionFee.acre,
initializedAt: dateToUnixTimestamp(),
// The message is signed immediately after the initialization.
finalizedAt: dateToUnixTimestamp(),
}

if (oldData) return [newActivity, ...oldData]
return [newActivity]
},
)
},
onSuccess: onSignMessageSuccess,
Expand Down
8 changes: 4 additions & 4 deletions dapp/src/components/TransactionModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useEffect } from "react"
import { StakeFlowProvider } from "#/contexts"
import {
useActivities,
useAppDispatch,
useFetchActivities,
useIsSignedMessage,
useTransactionModal,
} from "#/hooks"
Expand All @@ -18,7 +18,7 @@ type TransactionModalProps = { type: ActionFlowType } & BaseModalProps

function TransactionModalBase({ type, closeModal }: TransactionModalProps) {
const dispatch = useAppDispatch()
const fetchActivities = useFetchActivities()
const { refetch: refetchActivities } = useActivities()

useEffect(() => {
dispatch(setType(type))
Expand All @@ -28,9 +28,9 @@ function TransactionModalBase({ type, closeModal }: TransactionModalProps) {
useEffect(() => {
return () => {
dispatch(resetState())
logPromiseFailure(fetchActivities())
logPromiseFailure(refetchActivities())
}
}, [dispatch, fetchActivities])
}, [dispatch, refetchActivities])

return (
<StakeFlowProvider>
Expand Down
1 change: 1 addition & 0 deletions dapp/src/constants/queryKeysFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const userKeys = {
all: ["user"] as const,
balance: () => [...userKeys.all, "balance"] as const,
position: () => [...userKeys.all, "position"] as const,
activities: () => [...userKeys.all, "activities"] as const,
pointsData: () => [...userKeys.all, "points-data"] as const,
}

Expand Down
9 changes: 6 additions & 3 deletions dapp/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@ export * from "./useVerifyDepositAddress"
export { default as useStatistics } from "./useStatistics"
export * from "./useDisconnectWallet"
export { default as useWalletConnectionAlert } from "./useWalletConnectionAlert"
export { default as useInvalidateQueries } from "./useInvalidateQueries"
export { default as useResetWalletState } from "./useResetWalletState"
export { default as useMobileMode } from "./useMobileMode"
export { default as useBitcoinRecoveryAddress } from "./useBitcoinRecoveryAddress"
export { default as useIsFetchedWalletData } from "./useIsFetchedWalletData"
export { default as useLocalStorage } from "./useLocalStorage"
export { default as useReferral } from "./useReferral"
export { default as useMats } from "./useMats"
export { default as useIsEmbed } from "./useIsEmbed"
export { default as useTriggerConnectWalletModal } from "./useTriggerConnectWalletModal"
export { default as useLastUsedBtcAddress } from "./useLastUsedBtcAddress"
export { default as useAcrePoints } from "./useAcrePoints"
export { default as useAggregatedAcrePointsData } from "./useAggregatedAcrePointsData"
export { default as useSignMessageAndCreateSession } from "./useSignMessageAndCreateSession"
export { default as useAccessCode } from "./useAccessCode"
export { default as useFormField } from "./useFormField"
export { default as useDepositBTCTransaction } from "./useDepositBTCTransaction"
export { default as useCancelPromise } from "./useCancelPromise"
export { default as useActivitiesCount } from "./useActivitiesCount"
export { default as useActivities } from "./useActivities"
export { default as useBitcoinBalance } from "./useBitcoinBalance"
export { default as useBitcoinPosition } from "./useBitcoinPosition"
export { default as useMats } from "./useMats"
1 change: 0 additions & 1 deletion dapp/src/hooks/orangeKit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export * from "./useConnectors"
export * from "./useAccountsChangedUnisat"
export * from "./useAccountsChangedOKX"
export * from "./useAccountChangedOKX"
export { default as useBitcoinBalance } from "./useBitcoinBalance"
2 changes: 0 additions & 2 deletions dapp/src/hooks/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
export * from "./useInitializeAcreSdk"
export * from "./useFetchMinDepositAmount"
export * from "./useInitDataFromSdk"
export * from "./useFetchActivities"
export * from "./useMinWithdrawAmount"
export { default as useBitcoinPosition } from "./useBitcoinPosition"
41 changes: 0 additions & 41 deletions dapp/src/hooks/sdk/useFetchActivities.ts

This file was deleted.

19 changes: 0 additions & 19 deletions dapp/src/hooks/sdk/useInitDataFromSdk.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
import { useEffect } from "react"
import { useInterval } from "@chakra-ui/react"
import { logPromiseFailure } from "#/utils"
import { REFETCH_INTERVAL_IN_MILLISECONDS } from "#/constants"
import { useFetchMinDepositAmount } from "./useFetchMinDepositAmount"
import { useFetchActivities } from "./useFetchActivities"
import { useWallet } from "../useWallet"

export function useInitDataFromSdk() {
const { address } = useWallet()
const fetchActivities = useFetchActivities()

useEffect(() => {
if (address) {
logPromiseFailure(fetchActivities())
}
}, [address, fetchActivities])

useFetchMinDepositAmount()
useInterval(
() => logPromiseFailure(fetchActivities()),
REFETCH_INTERVAL_IN_MILLISECONDS,
)
}
4 changes: 1 addition & 3 deletions dapp/src/hooks/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ export * from "./useActionFlowStatus"
export * from "./useActionFlowActiveStep"
export * from "./useActionFlowTokenAmount"
export * from "./useActionFlowTxHash"
export * from "./useAllActivitiesCount"
export * from "./useActionFlowPause"
export * from "./useIsSignedMessage"
export { default as useHasFetchedActivities } from "./useHasFetchedActivities"
export { default as useActivities } from "./useActivities"
export { default as useWalletAddress } from "./useWalletAddress"
9 changes: 0 additions & 9 deletions dapp/src/hooks/store/useActivities.ts

This file was deleted.

6 changes: 0 additions & 6 deletions dapp/src/hooks/store/useAllActivitiesCount.ts

This file was deleted.

8 changes: 0 additions & 8 deletions dapp/src/hooks/store/useHasFetchedActivities.ts

This file was deleted.

6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useWalletAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectWalletAddress } from "#/store/wallet"
import { useAppSelector } from "./useAppSelector"

export default function useWalletAddress() {
return useAppSelector(selectWalletAddress)
}
13 changes: 13 additions & 0 deletions dapp/src/hooks/useAcrePointsData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { queryKeysFactory, REFETCH_INTERVAL_IN_MILLISECONDS } from "#/constants"
import { useQuery } from "@tanstack/react-query"
import { acreApi } from "#/utils"

const { acreKeys } = queryKeysFactory

export default function useAcrePointsData() {
return useQuery({
queryKey: [...acreKeys.pointsData()],
queryFn: async () => acreApi.getPointsData(),
refetchInterval: REFETCH_INTERVAL_IN_MILLISECONDS,
})
}
Loading
Loading