From 5df4b8a258c420916336885763080274dd35a4a6 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 10 May 2024 11:24:23 +0200 Subject: [PATCH 1/4] Create a special hook for triggering `TransactionModal` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After clicking on the “Deposit BTC” button, we should first call the Ledger Live native window to select an account. Once the account has been selected we open the right transaction modal to the user. --- .../TransactionModal/ActionFormModal.tsx | 4 +-- .../TransactionModal/ErrorModal.tsx | 4 +-- dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useModal.ts | 11 ++++-- dapp/src/hooks/useRequestBitcoinAccount.ts | 2 +- dapp/src/hooks/useRequestEthereumAccount.ts | 2 +- dapp/src/hooks/useTransactionModal.ts | 34 +++++++++++++++++++ .../pages/DashboardPage/PositionDetails.tsx | 18 ++++------ .../LandingPage/components/HeroSection.tsx | 8 ++--- dapp/src/store/action-flow/actionFlowSlice.ts | 3 +- dapp/src/types/action-flow.ts | 4 +-- dapp/src/types/ledger-live-app.ts | 3 +- 12 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 dapp/src/hooks/useTransactionModal.ts diff --git a/dapp/src/components/TransactionModal/ActionFormModal.tsx b/dapp/src/components/TransactionModal/ActionFormModal.tsx index dff2cc2a8..13e6b1ae1 100644 --- a/dapp/src/components/TransactionModal/ActionFormModal.tsx +++ b/dapp/src/components/TransactionModal/ActionFormModal.tsx @@ -19,11 +19,11 @@ const FORM_DATA: Record< ) => React.ReactNode } > = { - stake: { + [ACTION_FLOW_TYPES.STAKE]: { header: "Deposit", FormComponent: StakeFormModal, }, - unstake: { + [ACTION_FLOW_TYPES.UNSTAKE]: { header: "Withdraw", FormComponent: UnstakeFormModal, }, diff --git a/dapp/src/components/TransactionModal/ErrorModal.tsx b/dapp/src/components/TransactionModal/ErrorModal.tsx index 92e343c31..64deb9259 100644 --- a/dapp/src/components/TransactionModal/ErrorModal.tsx +++ b/dapp/src/components/TransactionModal/ErrorModal.tsx @@ -1,9 +1,9 @@ import React from "react" -import { ActionFlowType } from "#/types" +import { ACTION_FLOW_TYPES, ActionFlowType } from "#/types" import StakingErrorModal from "./ActiveStakingStep/StakingErrorModal" export default function ErrorModal({ type }: { type: ActionFlowType }) { - if (type === "stake") return + if (type === ACTION_FLOW_TYPES.STAKE) return // TODO: Handle the case of unstake action return null } diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index b3405e7be..448d552e9 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -25,3 +25,4 @@ export * from "./useSize" export * from "./router" export * from "./useTransactionFee" export * from "./useModal" +export * from "./useTransactionModal" diff --git a/dapp/src/hooks/useModal.ts b/dapp/src/hooks/useModal.ts index 8d213e785..c1a38e3c0 100644 --- a/dapp/src/hooks/useModal.ts +++ b/dapp/src/hooks/useModal.ts @@ -5,6 +5,7 @@ import { selectModalType, } from "#/store/modal" import { ModalProps, ModalType } from "#/types" +import { useCallback } from "react" import { useAppDispatch } from "./store/useAppDispatch" import { useAppSelector } from "./store/useAppSelector" @@ -13,10 +14,14 @@ export function useModal() { const modalProps = useAppSelector(selectModalProps) const dispatch = useAppDispatch() - const handleOpenModal = (type: ModalType, props?: ModalProps) => - dispatch(openModal({ modalType: type, props })) + const handleOpenModal = useCallback( + (type: ModalType, props?: ModalProps) => { + dispatch(openModal({ modalType: type, props })) + }, + [dispatch], + ) - const handleCloseModal = () => dispatch(closeModal()) + const handleCloseModal = useCallback(() => dispatch(closeModal()), [dispatch]) return { modalType, diff --git a/dapp/src/hooks/useRequestBitcoinAccount.ts b/dapp/src/hooks/useRequestBitcoinAccount.ts index 7800adffb..834500e38 100644 --- a/dapp/src/hooks/useRequestBitcoinAccount.ts +++ b/dapp/src/hooks/useRequestBitcoinAccount.ts @@ -22,5 +22,5 @@ export function useRequestBitcoinAccount(): UseRequestAccountReturn { walletApiReactTransport.disconnect() }, [requestAccount, walletApiReactTransport]) - return { requestAccount: requestBitcoinAccount } + return { account, requestAccount: requestBitcoinAccount } } diff --git a/dapp/src/hooks/useRequestEthereumAccount.ts b/dapp/src/hooks/useRequestEthereumAccount.ts index 1fa5c1f16..e6ed33060 100644 --- a/dapp/src/hooks/useRequestEthereumAccount.ts +++ b/dapp/src/hooks/useRequestEthereumAccount.ts @@ -22,5 +22,5 @@ export function useRequestEthereumAccount(): UseRequestAccountReturn { walletApiReactTransport.disconnect() }, [requestAccount, walletApiReactTransport]) - return { requestAccount: requestEthereumAccount } + return { account, requestAccount: requestEthereumAccount } } diff --git a/dapp/src/hooks/useTransactionModal.ts b/dapp/src/hooks/useTransactionModal.ts new file mode 100644 index 000000000..de88a67cb --- /dev/null +++ b/dapp/src/hooks/useTransactionModal.ts @@ -0,0 +1,34 @@ +import { ActionFlowType, MODAL_TYPES } from "#/types" +import { useCallback, useEffect } from "react" +import { logPromiseFailure } from "#/utils" +import { useModal } from "./useModal" +import { useWalletContext } from "./useWalletContext" +import { useRequestBitcoinAccount } from "./useRequestBitcoinAccount" + +export function useTransactionModal(type: ActionFlowType) { + const { btcAccount } = useWalletContext() + const { account, requestAccount } = useRequestBitcoinAccount() + const { openModal } = useModal() + + const handleOpenModal = useCallback(() => { + openModal(MODAL_TYPES[type], { type }) + }, [openModal, type]) + + useEffect(() => { + // We should check the `account` here from `useRequestBitcoinAccount`. + // This will allow us to check there whether the account request action + // called earlier was successful. + // Checking the `btcAccount` may trigger a not needed modal opening. + if (account) { + handleOpenModal() + } + }, [account, handleOpenModal, openModal, type]) + + return useCallback(() => { + if (btcAccount) { + handleOpenModal() + } else { + logPromiseFailure(requestAccount()) + } + }, [btcAccount, handleOpenModal, requestAccount]) +} diff --git a/dapp/src/pages/DashboardPage/PositionDetails.tsx b/dapp/src/pages/DashboardPage/PositionDetails.tsx index 8a432b9f1..8089ce51f 100644 --- a/dapp/src/pages/DashboardPage/PositionDetails.tsx +++ b/dapp/src/pages/DashboardPage/PositionDetails.tsx @@ -9,15 +9,16 @@ import { } from "@chakra-ui/react" import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion" import { TextMd } from "#/components/shared/Typography" -import { MODAL_TYPES } from "#/types" +import { ACTION_FLOW_TYPES } from "#/types" import { useEstimatedBTCBalance } from "#/hooks/store" import { LiquidStakingTokenPopover } from "#/components/LiquidStakingTokenPopover" -import { useModal, useSize } from "#/hooks" +import { useSize, useTransactionModal } from "#/hooks" export default function PositionDetails(props: CardProps) { const estimatedBtcBalance = useEstimatedBTCBalance() const { ref, size } = useSize() - const { openModal } = useModal() + const openDepositModal = useTransactionModal(ACTION_FLOW_TYPES.STAKE) + const openWithdrawModal = useTransactionModal(ACTION_FLOW_TYPES.UNSTAKE) return ( @@ -40,17 +41,10 @@ export default function PositionDetails(props: CardProps) { /> - - diff --git a/dapp/src/pages/LandingPage/components/HeroSection.tsx b/dapp/src/pages/LandingPage/components/HeroSection.tsx index 280f2a710..bdba8106e 100644 --- a/dapp/src/pages/LandingPage/components/HeroSection.tsx +++ b/dapp/src/pages/LandingPage/components/HeroSection.tsx @@ -1,10 +1,10 @@ import React from "react" import { Button, Heading, VStack, Text } from "@chakra-ui/react" -import { useModal } from "#/hooks" -import { MODAL_TYPES } from "#/types" +import { useTransactionModal } from "#/hooks" +import { ACTION_FLOW_TYPES } from "#/types" export default function HeroSection() { - const { openModal } = useModal() + const openTransactionModal = useTransactionModal(ACTION_FLOW_TYPES.STAKE) return ( @@ -29,7 +29,7 @@ export default function HeroSection() { fontWeight="bold" lineHeight={6} h="auto" - onClick={() => openModal(MODAL_TYPES.STAKE, { type: "stake" })} + onClick={openTransactionModal} > Deposit BTC diff --git a/dapp/src/store/action-flow/actionFlowSlice.ts b/dapp/src/store/action-flow/actionFlowSlice.ts index a1fdf4c2f..cf650d70c 100644 --- a/dapp/src/store/action-flow/actionFlowSlice.ts +++ b/dapp/src/store/action-flow/actionFlowSlice.ts @@ -1,4 +1,5 @@ import { + ACTION_FLOW_TYPES, ActionFlowType, PROCESS_STATUSES, ProcessStatus, @@ -14,7 +15,7 @@ type ActionFlowState = { } const initialState: ActionFlowState = { - type: "stake", + type: ACTION_FLOW_TYPES.STAKE, activeStep: 1, status: PROCESS_STATUSES.IDLE, tokenAmount: undefined, diff --git a/dapp/src/types/action-flow.ts b/dapp/src/types/action-flow.ts index a587b58b9..6e870647f 100644 --- a/dapp/src/types/action-flow.ts +++ b/dapp/src/types/action-flow.ts @@ -1,6 +1,6 @@ export const ACTION_FLOW_TYPES = { - STAKE: "stake", - UNSTAKE: "unstake", + STAKE: "STAKE", + UNSTAKE: "UNSTAKE", } as const export type ActionFlowType = diff --git a/dapp/src/types/ledger-live-app.ts b/dapp/src/types/ledger-live-app.ts index 8e82cb1a3..c2e452ca0 100644 --- a/dapp/src/types/ledger-live-app.ts +++ b/dapp/src/types/ledger-live-app.ts @@ -1,9 +1,10 @@ -import { WalletAPIClient } from "@ledgerhq/wallet-api-client" +import { Account, WalletAPIClient } from "@ledgerhq/wallet-api-client" export type RequestAccountParams = Parameters< WalletAPIClient["account"]["request"] > export type UseRequestAccountReturn = { + account: Account | null requestAccount: (...params: RequestAccountParams) => Promise } From eebe5b5fc82e735f5427f4bb7f1b546bc06e3c76 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 14 May 2024 15:16:43 +0200 Subject: [PATCH 2/4] Setting maintainer address for Sepolia --- solidity/hardhat.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts index 41f2d48fe..904105565 100644 --- a/solidity/hardhat.config.ts +++ b/solidity/hardhat.config.ts @@ -106,7 +106,7 @@ const config: HardhatUserConfig = { }, maintainer: { default: 4, - sepolia: 0, // TODO: updated to the actual address once available + sepolia: "0x5CD05b073Ed2d01991A46cd55dA5D10a63B1E2CA", mainnet: "", // TODO: updated to the actual address once available integration: 0, // TODO: update to the same value as mainnet }, From 6745b0c3f25908864e3dc3597025d4c386f8ab73 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 15 May 2024 07:35:06 +0200 Subject: [PATCH 3/4] Use `useTransactionModal` in new dashboard --- dapp/src/pages/DashboardPage/DashboardCard.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dapp/src/pages/DashboardPage/DashboardCard.tsx b/dapp/src/pages/DashboardPage/DashboardCard.tsx index 459132cc8..ee6caf612 100644 --- a/dapp/src/pages/DashboardPage/DashboardCard.tsx +++ b/dapp/src/pages/DashboardPage/DashboardCard.tsx @@ -15,9 +15,9 @@ import { TextMd } from "#/components/shared/Typography" import IconTag from "#/components/shared/IconTag" import { BoostArrowIcon } from "#/assets/icons" import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion" -import { AmountType, MODAL_TYPES } from "#/types" +import { ACTION_FLOW_TYPES, AmountType } from "#/types" import { ActivitiesList } from "#/components/shared/ActivitiesList" -import { useModal } from "#/hooks" +import { useTransactionModal } from "#/hooks" const buttonStyles: ButtonProps = { size: "lg", @@ -37,7 +37,7 @@ type DashboardCardProps = CardProps & { export default function DashboardCard(props: DashboardCardProps) { const { bitcoinAmount, positionPercentage, ...restProps } = props - const { openModal } = useModal() + const openDepositModal = useTransactionModal(ACTION_FLOW_TYPES.STAKE) return ( @@ -87,10 +87,7 @@ export default function DashboardCard(props: DashboardCardProps) { -