Skip to content

Commit

Permalink
feat(billing): update transactional messages for managed wallet
Browse files Browse the repository at this point in the history
refs #247
  • Loading branch information
ygrishajev committed Aug 8, 2024
1 parent e9cc512 commit efc0508
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 30 deletions.
45 changes: 33 additions & 12 deletions apps/deploy-web/src/components/layout/TransactionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<Props> = ({ state, open, onClose }) => {
return (
const TITLES: Record<LoadingState, string> = {
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<Props> = ({ state, onClose }) => {
return state ? (
<Popup
fullWidth
open={open}
open={!!state}
variant="custom"
title={
state === "waitingForApproval" ? <div className="text-center">Waiting for tx approval</div> : <div className="text-center">Transaction Pending</div>
}
title={<div className="text-center">{TITLES[state]}</div>}
actions={[]}
onClose={onClose}
maxWidth="xs"
Expand All @@ -29,10 +48,12 @@ export const TransactionModal: React.FunctionComponent<Props> = ({ state, open,
<Spinner size="large" className="flex justify-center" />
</div>

<div className="text-sm text-muted-foreground">
{state === "waitingForApproval" ? "APPROVE OR REJECT TX TO CONTINUE..." : "BROADCASTING TRANSACTION..."}
</div>
{CRYPTO_STATES.includes(state) && (
<div className="text-sm text-muted-foreground">
{state === "waitingForApproval" ? "APPROVE OR REJECT TX TO CONTINUE..." : "BROADCASTING TRANSACTION..."}
</div>
)}
</div>
</Popup>
);
) : null;
};
47 changes: 29 additions & 18 deletions apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -61,11 +61,17 @@ type ContextType = {

const WalletProviderContext = React.createContext<ContextType>({} as ContextType);

const MESSAGE_STATES: Record<string, LoadingState> = {
"/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<Balances | null>(null);
const [isWalletLoaded, setIsWalletLoaded] = useState<boolean>(true);
const [isBroadcastingTx, setIsBroadcastingTx] = useState<boolean>(false);
const [isWaitingForApproval, setIsWaitingForApproval] = useState<boolean>(false);
const [loadingState, setLoadingState] = useState<LoadingState | undefined>(undefined);
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const signingClient = useRef<SigningStargateClient | null>(null);
const router = useRouter();
Expand Down Expand Up @@ -176,40 +182,46 @@ export const WalletProvider = ({ children }) => {
}

async function signAndBroadcastTx(msgs: EncodeObject[]): Promise<boolean> {
setIsWaitingForApproval(true);
let pendingSnackbarKey: SnackbarKey | null = null;
const enqueueTxSnackbar = () => {
pendingSnackbarKey = enqueueSnackbar(<Snackbar title="Broadcasting transaction..." subTitle="Please wait a few seconds" showLoading />, {
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(<Snackbar title="Broadcasting transaction..." subTitle="Please wait a few seconds" showLoading />, {
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",
Expand Down Expand Up @@ -264,8 +276,7 @@ export const WalletProvider = ({ children }) => {
closeSnackbar(pendingSnackbarKey);
}

setIsWaitingForApproval(false);
setIsBroadcastingTx(false);
setLoadingState(undefined);
}
}

Expand Down Expand Up @@ -345,7 +356,7 @@ export const WalletProvider = ({ children }) => {
>
{children}

<TransactionModal open={isWaitingForApproval || isBroadcastingTx} state={isWaitingForApproval ? "waitingForApproval" : "broadcasting"} />
<TransactionModal state={loadingState} />
</WalletProviderContext.Provider>
);
};
Expand Down

0 comments on commit efc0508

Please sign in to comment.