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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
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
Expand Up @@ -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 Down Expand Up @@ -62,10 +60,8 @@ export default function DepositBTCModal() {
[onError, handlePause],
)

const { sendBitcoinTransaction, transactionHash } = useDepositBTCTransaction(
onDepositBTCSuccess,
onDepositBTCError,
)
const { sendBitcoinTransaction, transactionHash, inProgress } =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename inProgress to isInProgress to keep consistency with other boolean values. Or if you agree to refactor the useDepositBTCTransaction hook as I mentioned above, we can use status.

useDepositBTCTransaction(onDepositBTCSuccess, onDepositBTCError)

useEffect(() => {
if (transactionHash) {
Expand Down Expand Up @@ -95,22 +91,10 @@ export default function DepositBTCModal() {
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 (inProgress || transactionHash)
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.

95 changes: 95 additions & 0 deletions dapp/src/components/TransactionModal/WalletInteractionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from "react"
import {
AlertDescription,
ModalBody,
ModalCloseButton,
ModalHeader,
Image,
HStack,
Progress,
ProgressProps,
} from "@chakra-ui/react"
import { AcreSignIcon } from "#/assets/icons"
import { useActionFlowType, useConnector } from "#/hooks"
import { ACTION_FLOW_TYPES } from "#/types"
import { Alert, AlertIcon } from "../shared/Alert"
import { TextMd } from "../shared/Typography"

const ICON_STYLES = {
boxSize: 14,
rounded: "full",
}

type WalletInteractionStep = "opening-wallet" | "awaiting-transaction"

const DATA: Record<
WalletInteractionStep,
{
header: string
description: (action: string) => string
progressProps?: ProgressProps
}
> = {
"opening-wallet": {
header: "Opening your wallet for signature",
description: (action) =>
`Confirm the ${action} by signing the transaction with your wallet.`,
},
"awaiting-transaction": {
header: "Awaiting signature confirmation",
description: () => "Waiting for your wallet to confirm the transaction.",
progressProps: { transform: "scaleX(-1)" },
},
}

export default function WalletInteractionModal({
step,
}: {
step: WalletInteractionStep
}) {
const actionType = useActionFlowType()
const connector = useConnector()
const { header, description, progressProps } = DATA[step]

return (
<>
{step === "opening-wallet" && <ModalCloseButton />}
<ModalHeader textAlign="center" pt={16} pb={12}>
{header}
</ModalHeader>
<ModalBody gap={12}>
<HStack minW={80} spacing={5}>
<AcreSignIcon {...ICON_STYLES} />
{/* TODO: Create correct progress bar */}
<Progress
size="sm"
bg="gold.200"
isIndeterminate
{...progressProps}
/>
<Image
src={connector?.icon}
p={2}
bg="black"
alt="Connector icon"
{...ICON_STYLES}
/>
</HStack>
<TextMd>
{description(
actionType === ACTION_FLOW_TYPES.STAKE ? "deposit" : "withdraw",
)}
</TextMd>
{step === "awaiting-transaction" && (
<Alert variant="elevated">
<AlertIcon />
<AlertDescription>
<TextMd>This may take up to a minute.</TextMd>
<TextMd>Don&apos;t close this window.</TextMd>
</AlertDescription>
</Alert>
)}
</ModalBody>
</>
)
}
Loading
Loading