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

Update screens for deposit and withdrawal flows #821

Merged
merged 18 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions dapp/src/acre-react/hooks/useInitializeWithdraw.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback } from "react"
import {
DataBuiltStepCallback,
MessageSignedStepCallback,
OnSignMessageStepCallback,
} from "@acre-btc/sdk/dist/src/lib/redeemer-proxy"
Expand All @@ -11,13 +12,15 @@ export default function useInitializeWithdraw() {
return useCallback(
async (
amount: bigint,
dataBuiltStepCallback?: DataBuiltStepCallback,
onSignMessageStep?: OnSignMessageStepCallback,
messageSignedStep?: MessageSignedStepCallback,
) => {
if (!acre || !isConnected) throw new Error("Account not connected")

return acre.account.initializeWithdrawal(
amount,
dataBuiltStepCallback,
onSignMessageStep,
messageSignedStep,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from "react"
import React, { useCallback } from "react"
import {
useActionFlowPause,
useActionFlowTokenAmount,
Expand All @@ -11,12 +11,10 @@ import {
} from "#/hooks"
import { eip1193, logPromiseFailure } from "#/utils"
import { PROCESS_STATUSES } from "#/types"
import { Highlight, ModalCloseButton } from "@chakra-ui/react"
import { TextMd } from "#/components/shared/Typography"
import { setStatus, setTxHash } from "#/store/action-flow"
import { queryKeysFactory } from "#/constants"
import { Alert, AlertIcon, AlertDescription } from "#/components/shared/Alert"
import TriggerTransactionModal from "../TriggerTransactionModal"
import { ONE_SEC_IN_MILLISECONDS, queryKeysFactory } from "#/constants"
import { useTimeout } from "@chakra-ui/react"
import WalletInteractionModal from "../WalletInteractionModal"

const { userKeys } = queryKeysFactory

Expand All @@ -36,81 +34,68 @@ export default function DepositBTCModal() {
}, [dispatch, handleBitcoinBalanceInvalidation])

const onError = useCallback(
(error?: unknown) => {
console.error(error)
dispatch(setStatus(PROCESS_STATUSES.FAILED))
},
() => dispatch(setStatus(PROCESS_STATUSES.FAILED)),
[dispatch],
r-czajkowski marked this conversation as resolved.
Show resolved Hide resolved
)

const handleStake = useExecuteFunction(stake, onStakeBTCSuccess, onError)

const onDepositBTCSuccess = useCallback(() => {
dispatch(setStatus(PROCESS_STATUSES.LOADING))

logPromiseFailure(handleStake())
}, [dispatch, handleStake])
const onDepositBTCSuccess = useCallback(
(transactionHash: string) => {
dispatch(setTxHash(transactionHash))
logPromiseFailure(handleStake())
},
[dispatch, handleStake],
)

const onDepositBTCError = useCallback(
(error: unknown) => {
if (eip1193.didUserRejectRequest(error)) {
handlePause()
} else {
onError(error)
onError()
}
},
[onError, handlePause],
)

const { sendBitcoinTransaction, transactionHash } = useDepositBTCTransaction(
const { sendBitcoinTransaction, status } = useDepositBTCTransaction(
onDepositBTCSuccess,
onDepositBTCError,
)

useEffect(() => {
if (transactionHash) {
dispatch(setTxHash(transactionHash))
}
}, [dispatch, transactionHash])

const handledDepositBTC = useCallback(async () => {
if (!tokenAmount?.amount || !btcAddress || !depositReceipt) return
const status = await verifyDepositAddress(depositReceipt, btcAddress)
const verificationStatus = await verifyDepositAddress(
depositReceipt,
btcAddress,
)

if (status === "valid") {
await sendBitcoinTransaction(btcAddress, tokenAmount?.amount)
if (verificationStatus === "valid") {
sendBitcoinTransaction({
recipient: btcAddress,
amount: tokenAmount?.amount,
})
} else {
onError()
}
}, [
tokenAmount?.amount,
btcAddress,
depositReceipt,
onError,
verifyDepositAddress,
sendBitcoinTransaction,
tokenAmount?.amount,
onError,
])

const handledDepositBTCWrapper = useCallback(() => {
logPromiseFailure(handledDepositBTC())
}, [handledDepositBTC])

return (
<>
<ModalCloseButton />
<TriggerTransactionModal callback={handledDepositBTCWrapper}>
<Alert variant="elevated">
<AlertIcon />
<AlertDescription>
<TextMd>
<Highlight query="Rewards" styles={{ fontWeight: "bold" }}>
You will receive your Rewards once the deposit transaction is
completed.
</Highlight>
</TextMd>
</AlertDescription>
</Alert>
</TriggerTransactionModal>
</>
)
useTimeout(handledDepositBTCWrapper, ONE_SEC_IN_MILLISECONDS)

if (status === "pending" || status === "success")
return <WalletInteractionModal step="awaiting-transaction" />

return <WalletInteractionModal step="opening-wallet" />
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react"
import {
Button,
ModalBody,
ModalCloseButton,
ModalHeader,
} from "@chakra-ui/react"
import Spinner from "#/components/shared/Spinner"
import { TextMd } from "#/components/shared/Typography"

export default function BuildTransactionModal({
onClose,
}: {
onClose: () => void
}) {
return (
<>
<ModalCloseButton onClick={onClose} />
<ModalHeader>Building transaction data...</ModalHeader>
<ModalBody>
<Spinner size="xl" variant="filled" />
<TextMd>We are building your withdrawal data.</TextMd>
<Button size="lg" width="100%" variant="outline" onClick={onClose}>
Cancel
</Button>
</ModalBody>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,21 @@ import {
useExecuteFunction,
useInvalidateQueries,
useModal,
useTimeout,
useTransactionDetails,
} from "#/hooks"
import { ACTION_FLOW_TYPES, PROCESS_STATUSES } from "#/types"
import { Button, ModalCloseButton } from "@chakra-ui/react"
import { dateToUnixTimestamp, eip1193, logPromiseFailure } from "#/utils"
import { setStatus } from "#/store/action-flow"
import { useInitializeWithdraw } from "#/acre-react/hooks"
import { queryKeysFactory } from "#/constants"
import { ONE_SEC_IN_MILLISECONDS, queryKeysFactory } from "#/constants"
import { activityInitialized } from "#/store/wallet"
import TriggerTransactionModal from "../TriggerTransactionModal"
import BuildTransactionModal from "./BuildTransactionModal"
import WalletInteractionModal from "../WalletInteractionModal"

const { userKeys } = queryKeysFactory

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

const withdrawalStatusToContent: Record<
WithdrawalStatus,
{ title: string; subtitle: string }
> = {
"building-data": {
title: "Building transaction data...",
subtitle: "We are building your withdrawal data.",
},
signature: {
title: "Waiting signature...",
subtitle: "Please complete the signing process in your wallet.",
},
transaction: {
title: "Waiting for withdrawal initialization...",
subtitle: "Withdrawal initialization in progress...",
},
}
type WithdrawalStatus = "building-data" | "built-data" | "signature"

const sessionIdToPromise: Record<
number,
Expand Down Expand Up @@ -79,6 +62,11 @@ export default function SignMessageModal() {
}
}, [])

const dataBuiltStepCallback = useCallback(() => {
setWaitingStatus("built-data")
return Promise.resolve()
}, [])

const onSignMessageCallback = useCallback(async () => {
setWaitingStatus("signature")
return Promise.race([
Expand All @@ -87,12 +75,6 @@ export default function SignMessageModal() {
])
}, [])

const messageSignedCallback = useCallback(() => {
setWaitingStatus("transaction")
dispatch(setStatus(PROCESS_STATUSES.LOADING))
return Promise.resolve()
}, [dispatch])

const onSignMessageSuccess = useCallback(() => {
handleBitcoinPositionInvalidation()
dispatch(setStatus(PROCESS_STATUSES.SUCCEEDED))
Expand Down Expand Up @@ -121,8 +103,8 @@ export default function SignMessageModal() {

const { redemptionKey } = await initializeWithdraw(
amount,
dataBuiltStepCallback,
onSignMessageCallback,
messageSignedCallback,
)

dispatch(
Expand Down Expand Up @@ -167,8 +149,6 @@ export default function SignMessageModal() {
logPromiseFailure(handleSignMessage())
}, [handleSignMessage])

const { title, subtitle } = withdrawalStatusToContent[status]

const onClose = () => {
const currentSessionId = sessionId.current
const sessionData = sessionIdToPromise[currentSessionId]
Expand All @@ -183,18 +163,13 @@ export default function SignMessageModal() {
closeModal()
}

return (
<>
<ModalCloseButton onClick={onClose} />
<TriggerTransactionModal
title={title}
subtitle={subtitle}
callback={handleInitWithdrawAndSignMessageWrapper}
>
<Button size="lg" width="100%" variant="outline" onClick={onClose}>
Cancel
</Button>
</TriggerTransactionModal>
</>
)
useTimeout(handleInitWithdrawAndSignMessageWrapper, ONE_SEC_IN_MILLISECONDS)

if (status === "building-data")
return <BuildTransactionModal onClose={onClose} />

if (status === "built-data")
return <WalletInteractionModal step="opening-wallet" />

return <WalletInteractionModal step="awaiting-transaction" />
}
3 changes: 0 additions & 3 deletions dapp/src/components/TransactionModal/ModalContentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { BaseModalProps, PROCESS_STATUSES } from "#/types"
import React from "react"
import ActionFormModal from "./ActionFormModal"
import ErrorModal from "./ErrorModal"
import LoadingModal from "./LoadingModal"
import ResumeModal from "./ResumeModal"
import SuccessModal from "./SuccessModal"
import NotEnoughFundsModal from "./ActiveUnstakingStep/NotEnoughFundsModal"
Expand All @@ -25,8 +24,6 @@ export default function ModalContentWrapper({
if (!tokenAmount || status === PROCESS_STATUSES.REFINE_AMOUNT)
return <ActionFormModal type={type} />

if (status === PROCESS_STATUSES.LOADING) return <LoadingModal />

if (status === PROCESS_STATUSES.SUCCEEDED) return <SuccessModal type={type} />

if (status === PROCESS_STATUSES.FAILED)
Expand Down
32 changes: 0 additions & 32 deletions dapp/src/components/TransactionModal/TriggerTransactionModal.tsx

This file was deleted.

Loading
Loading