diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx
index 08926094e..6a0bf6e5e 100644
--- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx
+++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx
@@ -1,8 +1,9 @@
-import React, { useCallback } from "react"
+import React, { useCallback, useRef } from "react"
import {
useActionFlowPause,
useActionFlowTokenAmount,
useAppDispatch,
+ useCancelPromise,
useDepositBTCTransaction,
useInvalidateQueries,
useStakeFlowContext,
@@ -28,6 +29,12 @@ export default function DepositBTCModal() {
queryKey: userKeys.balance(),
})
+ const sessionId = useRef(Math.random())
+ const { cancel, resolve, sessionIdToPromise } = useCancelPromise(
+ sessionId.current,
+ "Deposit cancelled",
+ )
+
const onStakeBTCSuccess = useCallback(() => {
handleBitcoinBalanceInvalidation()
dispatch(setStatus(PROCESS_STATUSES.SUCCEEDED))
@@ -58,13 +65,15 @@ export default function DepositBTCModal() {
const onDepositBTCError = useCallback(
(error: unknown) => {
+ if (!sessionIdToPromise[sessionId.current].shouldOpenErrorModal) return
+
if (eip1193.didUserRejectRequest(error)) {
handlePause()
} else {
onError(error)
}
},
- [onError, handlePause],
+ [sessionIdToPromise, handlePause, onError],
)
const { mutate: sendBitcoinTransaction, status } = useDepositBTCTransaction({
@@ -79,6 +88,8 @@ export default function DepositBTCModal() {
btcAddress,
)
+ await resolve()
+
if (verificationStatus === "valid") {
sendBitcoinTransaction({
recipient: btcAddress,
@@ -92,6 +103,7 @@ export default function DepositBTCModal() {
btcAddress,
depositReceipt,
verifyDepositAddress,
+ resolve,
sendBitcoinTransaction,
onError,
])
@@ -105,5 +117,5 @@ export default function DepositBTCModal() {
if (status === "pending" || status === "success")
return
- return
+ return
}
diff --git a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx
index 915a9436a..877f83264 100644
--- a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx
+++ b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx
@@ -1,8 +1,9 @@
-import React, { useCallback, useEffect, useRef, useState } from "react"
+import React, { useCallback, useRef, useState } from "react"
import {
useActionFlowPause,
useActionFlowTokenAmount,
useAppDispatch,
+ useCancelPromise,
useInvalidateQueries,
useModal,
useTimeout,
@@ -22,15 +23,6 @@ const { userKeys } = queryKeysFactory
type WithdrawalStatus = "building-data" | "built-data" | "signature"
-const sessionIdToPromise: Record<
- number,
- {
- promise: Promise
- cancel: (reason: Error) => void
- shouldOpenErrorModal: boolean
- }
-> = {}
-
export default function SignMessageModal() {
const [status, setWaitingStatus] = useState("building-data")
@@ -44,24 +36,15 @@ export default function SignMessageModal() {
queryKey: userKeys.position(),
})
const sessionId = useRef(Math.random())
+ const { cancel, resolve, sessionIdToPromise } = useCancelPromise(
+ sessionId.current,
+ "Withdrawal cancelled",
+ )
const { transactionFee } = useTransactionDetails(
amount,
ACTION_FLOW_TYPES.UNSTAKE,
)
- useEffect(() => {
- let cancel = (_: Error) => {}
- const promise: Promise = new Promise((_, reject) => {
- cancel = reject
- })
-
- sessionIdToPromise[sessionId.current] = {
- cancel,
- promise,
- shouldOpenErrorModal: true,
- }
- }, [])
-
const dataBuiltStepCallback = useCallback(() => {
setWaitingStatus("built-data")
return Promise.resolve()
@@ -69,11 +52,8 @@ export default function SignMessageModal() {
const onSignMessageCallback = useCallback(async () => {
setWaitingStatus("signature")
- return Promise.race([
- sessionIdToPromise[sessionId.current].promise,
- Promise.resolve(),
- ])
- }, [])
+ return resolve()
+ }, [resolve])
const onSignMessageSuccess = useCallback(() => {
handleBitcoinPositionInvalidation()
@@ -98,7 +78,7 @@ export default function SignMessageModal() {
onSignMessageError(error)
}
},
- [onSignMessageError, handlePause],
+ [sessionIdToPromise, handlePause, onSignMessageError],
)
const { mutate: handleSignMessage } = useMutation({
@@ -151,16 +131,7 @@ export default function SignMessageModal() {
})
const onClose = () => {
- const currentSessionId = sessionId.current
- const sessionData = sessionIdToPromise[currentSessionId]
- sessionIdToPromise[currentSessionId] = {
- ...sessionData,
- shouldOpenErrorModal: false,
- }
-
- sessionIdToPromise[currentSessionId].cancel(
- new Error("Withdrawal cancelled"),
- )
+ cancel()
closeModal()
}
diff --git a/dapp/src/components/TransactionModal/WalletInteractionModal.tsx b/dapp/src/components/TransactionModal/WalletInteractionModal.tsx
index 8011648f6..8c3926d1f 100644
--- a/dapp/src/components/TransactionModal/WalletInteractionModal.tsx
+++ b/dapp/src/components/TransactionModal/WalletInteractionModal.tsx
@@ -50,8 +50,10 @@ const DATA: Record<
export default function WalletInteractionModal({
step,
+ onClose,
}: {
step: WalletInteractionStep
+ onClose?: () => void
}) {
const actionType = useActionFlowType()
const connector = useConnector()
@@ -60,7 +62,7 @@ export default function WalletInteractionModal({
return (
<>
- {step === "opening-wallet" && }
+ {step === "opening-wallet" && }
{header}
diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts
index 28bc42703..db36d2455 100644
--- a/dapp/src/hooks/index.ts
+++ b/dapp/src/hooks/index.ts
@@ -38,3 +38,4 @@ export { default as useScrollbarVisibility } from "./useScrollbarVisibility"
export { default as useAccessCode } from "./useAccessCode"
export { default as useFormField } from "./useFormField"
export { default as useDepositBTCTransaction } from "./useDepositBTCTransaction"
+export { default as useCancelPromise } from "./useCancelPromise"
diff --git a/dapp/src/hooks/useCancelPromise.ts b/dapp/src/hooks/useCancelPromise.ts
new file mode 100644
index 000000000..a6bb1666b
--- /dev/null
+++ b/dapp/src/hooks/useCancelPromise.ts
@@ -0,0 +1,50 @@
+import { useCallback, useEffect } from "react"
+
+const sessionIdToPromise: Record<
+ number,
+ {
+ promise: Promise
+ cancel: (reason: Error) => void
+ shouldOpenErrorModal: boolean
+ }
+> = {}
+
+export default function useCancelPromise(
+ sessionId: number,
+ errorMsgText: string,
+) {
+ useEffect(() => {
+ let cancel = (_: Error) => {}
+ const promise: Promise = new Promise((_, reject) => {
+ cancel = reject
+ })
+
+ sessionIdToPromise[sessionId] = {
+ cancel,
+ promise,
+ shouldOpenErrorModal: true,
+ }
+ }, [sessionId])
+
+ const cancel = useCallback(() => {
+ const sessionData = sessionIdToPromise[sessionId]
+ sessionIdToPromise[sessionId] = {
+ ...sessionData,
+ shouldOpenErrorModal: false,
+ }
+
+ sessionIdToPromise[sessionId].cancel(new Error(errorMsgText))
+ }, [errorMsgText, sessionId])
+
+ const resolve = useCallback(
+ () =>
+ Promise.race([sessionIdToPromise[sessionId].promise, Promise.resolve()]),
+ [sessionId],
+ )
+
+ return {
+ cancel,
+ resolve,
+ sessionIdToPromise,
+ }
+}
diff --git a/dapp/src/hooks/useTransactionModal.ts b/dapp/src/hooks/useTransactionModal.ts
index e052ed131..7e4b9d0be 100644
--- a/dapp/src/hooks/useTransactionModal.ts
+++ b/dapp/src/hooks/useTransactionModal.ts
@@ -1,4 +1,4 @@
-import { ACTION_FLOW_TYPES, ActionFlowType, MODAL_TYPES } from "#/types"
+import { ActionFlowType, MODAL_TYPES } from "#/types"
import { useCallback } from "react"
import { useModal } from "./useModal"
@@ -8,7 +8,7 @@ export function useTransactionModal(type: ActionFlowType) {
return useCallback(() => {
openModal(MODAL_TYPES[type], {
type,
- closeOnEsc: type !== ACTION_FLOW_TYPES.UNSTAKE,
+ closeOnEsc: false,
})
}, [openModal, type])
}