From efc050860cc459625259be7ac041e15ce49dcfc1 Mon Sep 17 00:00:00 2001 From: Yaroslav Grishajev Date: Tue, 6 Aug 2024 15:29:14 +0200 Subject: [PATCH] feat(billing): update transactional messages for managed wallet refs #247 --- .../components/layout/TransactionModal.tsx | 45 +++++++++++++----- .../context/WalletProvider/WalletProvider.tsx | 47 ++++++++++++------- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/apps/deploy-web/src/components/layout/TransactionModal.tsx b/apps/deploy-web/src/components/layout/TransactionModal.tsx index bb8d84cdc..2592fc707 100644 --- a/apps/deploy-web/src/components/layout/TransactionModal.tsx +++ b/apps/deploy-web/src/components/layout/TransactionModal.tsx @@ -2,22 +2,41 @@ import { ReactNode } from "react"; import { Popup, Spinner } from "@akashnetwork/ui/components"; +export type LoadingState = + | "waitingForApproval" + | "broadcasting" + | "searchingProviders" + | "creatingDeployment" + | "updatingDeployment" + | "creatingLease" + | "closingDeployment"; + type Props = { - state: "waitingForApproval" | "broadcasting"; - open: boolean; + managed?: boolean; + state?: LoadingState; onClose?: () => void; children?: ReactNode; }; -export const TransactionModal: React.FunctionComponent = ({ state, open, onClose }) => { - return ( +const TITLES: Record = { + waitingForApproval: "Waiting for tx approval", + broadcasting: "Transaction Pending", + searchingProviders: "Searching Providers", + creatingDeployment: "Creating Deployment", + updatingDeployment: "Updating Deployment", + creatingLease: "Creating Lease", + closingDeployment: "Closing Deployment" +}; + +const CRYPTO_STATES: LoadingState[] = ["waitingForApproval", "broadcasting"]; + +export const TransactionModal: React.FunctionComponent = ({ state, onClose }) => { + return state ? ( Waiting for tx approval :
Transaction Pending
- } + title={
{TITLES[state]}
} actions={[]} onClose={onClose} maxWidth="xs" @@ -29,10 +48,12 @@ export const TransactionModal: React.FunctionComponent = ({ state, open, -
- {state === "waitingForApproval" ? "APPROVE OR REJECT TX TO CONTINUE..." : "BROADCASTING TRANSACTION..."} -
+ {CRYPTO_STATES.includes(state) && ( +
+ {state === "waitingForApproval" ? "APPROVE OR REJECT TX TO CONTINUE..." : "BROADCASTING TRANSACTION..."} +
+ )}
- ); + ) : null; }; diff --git a/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx b/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx index 64220b875..95635af8c 100644 --- a/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx +++ b/apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx @@ -12,7 +12,7 @@ import { useRouter } from "next/navigation"; import { event } from "nextjs-google-analytics"; import { SnackbarKey, useSnackbar } from "notistack"; -import { TransactionModal } from "@src/components/layout/TransactionModal"; +import { LoadingState, TransactionModal } from "@src/components/layout/TransactionModal"; import { useAnonymousUser } from "@src/context/AnonymousUserProvider/AnonymousUserProvider"; import { useAllowance } from "@src/hooks/useAllowance"; import { useUsdcDenom } from "@src/hooks/useDenom"; @@ -61,11 +61,17 @@ type ContextType = { const WalletProviderContext = React.createContext({} as ContextType); +const MESSAGE_STATES: Record = { + "/akash.deployment.v1beta3.MsgCloseDeployment": "closingDeployment", + "/akash.deployment.v1beta3.MsgCreateDeployment": "searchingProviders", + "/akash.market.v1beta4.MsgCreateLease": "creatingDeployment", + "/akash.deployment.v1beta3.MsgUpdateDeployment": "updatingDeployment" +}; + export const WalletProvider = ({ children }) => { const [walletBalances, setWalletBalances] = useState(null); const [isWalletLoaded, setIsWalletLoaded] = useState(true); - const [isBroadcastingTx, setIsBroadcastingTx] = useState(false); - const [isWaitingForApproval, setIsWaitingForApproval] = useState(false); + const [loadingState, setLoadingState] = useState(undefined); const { enqueueSnackbar, closeSnackbar } = useSnackbar(); const signingClient = useRef(null); const router = useRouter(); @@ -176,40 +182,46 @@ export const WalletProvider = ({ children }) => { } async function signAndBroadcastTx(msgs: EncodeObject[]): Promise { - setIsWaitingForApproval(true); let pendingSnackbarKey: SnackbarKey | null = null; - const enqueueTxSnackbar = () => { - pendingSnackbarKey = enqueueSnackbar(, { - variant: "info", - autoHideDuration: null - }); - }; let txResult: TxOutput; try { if (user && managedWallet) { - enqueueTxSnackbar(); + const mainMessage = msgs.find(msg => msg.typeUrl in MESSAGE_STATES); + + if (mainMessage) { + setLoadingState(MESSAGE_STATES[mainMessage.typeUrl]); + } + txResult = await txHttpService.signAndBroadcastTx({ userId: user.id, messages: msgs }); } else { + const enqueueTxSnackbar = () => { + pendingSnackbarKey = enqueueSnackbar(, { + variant: "info", + autoHideDuration: null + }); + }; + setLoadingState("waitingForApproval"); const estimatedFees = await userWallet.estimateFee(msgs); const txRaw = await userWallet.sign(msgs, { ...estimatedFees, granter: feeGranter }); - setIsWaitingForApproval(false); - setIsBroadcastingTx(true); + setLoadingState("broadcasting"); enqueueTxSnackbar(); txResult = await userWallet.broadcast(txRaw); - setIsBroadcastingTx(false); + setLoadingState(undefined); } if (txResult.code !== 0) { throw new Error(txResult.rawLog); } - showTransactionSnackbar("Transaction success!", "", txResult.transactionHash, "success"); + if (!managedWallet?.isWalletConnected) { + showTransactionSnackbar("Transaction success!", "", txResult.transactionHash, "success"); + } event(AnalyticsEvents.SUCCESSFUL_TX, { category: "transactions", @@ -264,8 +276,7 @@ export const WalletProvider = ({ children }) => { closeSnackbar(pendingSnackbarKey); } - setIsWaitingForApproval(false); - setIsBroadcastingTx(false); + setLoadingState(undefined); } } @@ -345,7 +356,7 @@ export const WalletProvider = ({ children }) => { > {children} - + ); };