Skip to content

Commit

Permalink
Add tracking transactionStatus using callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
toddkao committed Sep 20, 2024
1 parent daf3781 commit df2ba12
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { SwapExecutionPageRouteSimple } from "./SwapExecutionPageRouteSimple";
import { SwapExecutionPageRouteDetailed } from "./SwapExecutionPageRouteDetailed";

import { withBoundProps } from "@/utils/misc";
import { txState } from "./SwapExecutionPageRouteDetailedRow";
import { useModal } from "@/components/Modal";
import { currentPageAtom, Routes } from "@/state/router";
import { ClientOperation, getClientOperations } from "@/utils/clientType";
Expand All @@ -36,10 +35,12 @@ const TX_DELAY_MS = 5_000;
export const SwapExecutionPage = () => {
const theme = useTheme();
const setCurrentPage = useSetAtom(currentPageAtom);
const { route } = useAtomValue(swapExecutionStateAtom);
const { route, operationExecutionDetailsArray } = useAtomValue(
swapExecutionStateAtom
);
const chainAddresses = useAtomValue(chainAddressesAtom);

const { connectRequiredChains } = useAutoSetAddress();
// const [{ data: transactionStatus }] = useAtom(skipTransactionStatus);

const clientOperations = useMemo(() => {
if (!route?.operations) return [] as ClientOperation[];
Expand All @@ -51,12 +52,6 @@ export const SwapExecutionPage = () => {
const [simpleRoute, setSimpleRoute] = useState(true);
const modal = useModal(ManualAddressModal);

const [txStateMap, _setTxStateMap] = useState<Record<number, txState>>({
0: "pending",
1: "pending",
2: "pending",
});

const { mutate, isPending, isSuccess } = useAtomValue(
skipSubmitSwapExecutionAtom
);
Expand All @@ -71,19 +66,19 @@ export const SwapExecutionPage = () => {
const lastChainAddress =
chainAddresses[requiredChainAddresses.length - 1]?.address;

if (!isPending) {
if (allAddressesSet) {
return SwapExecutionState.ready;
}
if (!lastChainAddress) {
return SwapExecutionState.destinationAddressUnset;
}
return SwapExecutionState.recoveryAddressUnset;
}
if (isSuccess) {
return SwapExecutionState.confirmed;
}
return SwapExecutionState.pending;
if (isPending) {
return SwapExecutionState.pending;
}
if (!lastChainAddress) {
return SwapExecutionState.destinationAddressUnset;
}
if (!allAddressesSet) {
return SwapExecutionState.recoveryAddressUnset;
}
return SwapExecutionState.ready;
}, [chainAddresses, isPending, isSuccess, route?.requiredChainAddresses]);

const renderMainButton = useMemo(() => {
Expand Down Expand Up @@ -165,8 +160,8 @@ export const SwapExecutionPage = () => {
}}
/>
<SwapExecutionPageRoute
txStateMap={txStateMap}
operations={clientOperations}
operationExecutionDetails={operationExecutionDetailsArray}
/>
{renderMainButton}
<SwapPageFooter showRouteInfo />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styled from "styled-components";
import { Column, Row } from "@/components/Layout";
import {
SwapExecutionPageRouteDetailedRow,
txState,
} from "./SwapExecutionPageRouteDetailedRow";
import { SwapExecutionBridgeIcon } from "@/icons/SwapExecutionBridgeIcon";
import { SwapExecutionSendIcon } from "@/icons/SwapExecutionSendIcon";
Expand All @@ -13,10 +12,11 @@ import { ClientOperation, OperationType } from "@/utils/clientType";
import { skipBridgesAtom, skipSwapVenuesAtom } from "@/state/skipClient";
import { useAtom } from "jotai";
import { getIsOperationSignRequired } from "@/utils/operations";
import { OperationExecutionDetails } from "@/state/swapExecutionPage";

export type SwapExecutionPageRouteDetailedProps = {
operations: ClientOperation[];
txStateMap: Record<number, txState>;
operationExecutionDetails: OperationExecutionDetails[];
};

type operationTypeToIcon = Record<OperationType, JSX.Element>;
Expand Down Expand Up @@ -50,7 +50,7 @@ type tooltipMap = Record<number, boolean>;

export const SwapExecutionPageRouteDetailed = ({
operations,
txStateMap,
operationExecutionDetails,
}: SwapExecutionPageRouteDetailedProps) => {
const [{ data: swapVenues }] = useAtom(skipSwapVenuesAtom);
const [{ data: bridges }] = useAtom(skipBridgesAtom);
Expand Down Expand Up @@ -78,7 +78,8 @@ export const SwapExecutionPageRouteDetailed = ({
tokenAmount={firstOperation.amountIn}
denom={firstOperation.denomIn}
chainID={firstOperation.fromChainID}
txState={"pending"}
explorerLink={operationExecutionDetails[0]?.explorerLink}
txState={operationExecutionDetails[0]?.status}
key={`first-row-${firstOperation?.denomIn}`}
context="source"
index={0}
Expand Down Expand Up @@ -135,12 +136,8 @@ export const SwapExecutionPageRouteDetailed = ({
index={index}
context={index === operations.length - 1 ? "destination" : "intermediary"}
isSignRequired={isSignRequired}
txState={txStateMap[index]}
explorerLink={
txStateMap[index] !== "pending"
? "https://www.google.com/"
: undefined
}
txState={operationExecutionDetails[index]?.status}
explorerLink={operationExecutionDetails[index]?.explorerLink}
key={`row-${asset?.denom}-${index}`}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export const SwapExecutionPageRouteDetailedRow = ({
tokenAmount,
});

console.log(explorerLink);

const chainAddresses = useAtomValue(chainAddressesAtom);
const account = useAccount(chainID);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import styled, { useTheme } from "styled-components";
import { Column } from "@/components/Layout";
import { txState } from "./SwapExecutionPageRouteDetailedRow";
import { useAtom } from "jotai";
import { SwapExecutionPageRouteSimpleRow } from "./SwapExecutionPageRouteSimpleRow";
import { BridgeArrowIcon } from "@/icons/BridgeArrowIcon";
import { ICONS } from "@/icons";
import { destinationWalletAtom } from "@/state/swapPage";
import { ClientOperation } from "@/utils/clientType";
import { OperationExecutionDetails } from "@/state/swapExecutionPage";

export type SwapExecutionPageRouteSimpleProps = {
operations: ClientOperation[];
txStateMap: Record<number, txState>;
operationExecutionDetails: OperationExecutionDetails[];
onClickEditDestinationWallet?: () => void;
};

export const SwapExecutionPageRouteSimple = ({
operations,
txStateMap,
operationExecutionDetails,
onClickEditDestinationWallet,
}: SwapExecutionPageRouteSimpleProps) => {
const theme = useTheme();

const [destinationWallet] = useAtom(destinationWalletAtom);

const firstOperation = operations[0];
const overallSwapState = getOverallSwapState(txStateMap);
const overallSwapState = getOverallSwapState(operationExecutionDetails);
const lastOperation = operations[operations.length - 1];
const sourceDenom = firstOperation.denomIn;
const destinationDenom = lastOperation.denomOut;
Expand Down Expand Up @@ -55,24 +55,20 @@ export const SwapExecutionPageRouteSimple = ({
icon={ICONS.pen}
txState={overallSwapState}
onClickEditDestinationWallet={onClickEditDestinationWallet}
explorerLink={
overallSwapState !== "pending" ? "https://www.google.com/" : undefined
}
explorerLink={operationExecutionDetails[operationExecutionDetails.length - 1]?.explorerLink}
/>
</StyledSwapExecutionPageRoute>
);
};

const getOverallSwapState = (txStateMap: Record<number, txState>) => {
const txStateArray = Object.values(txStateMap);

if (txStateArray.find((state) => state === "failed")) {
const getOverallSwapState = (operationExecutionDetails: OperationExecutionDetails[]) => {
if (operationExecutionDetails.find((state) => state.status === "failed")) {
return "failed";
} else if (txStateArray.find((state) => state === "broadcasted")) {
} else if (operationExecutionDetails.find((state) => state.status === "broadcasted")) {
return "broadcasted";
} else if (txStateArray.every((state) => state === "pending")) {
} else if (operationExecutionDetails.every((state) => state.status === "pending")) {
return "pending";
} else if (txStateArray.every((state) => state === "confirmed")) {
} else if (operationExecutionDetails.every((state) => state.status === "confirmed")) {
return "confirmed";
}
};
Expand Down
6 changes: 3 additions & 3 deletions packages/widget-v2/src/pages/SwapPage/SwapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
destinationAssetAmountAtom,
isWaitingForNewRouteAtom,
} from "@/state/swapPage";
import { swapExecutionStateAtom } from "@/state/swapExecutionPage";
import { setSwapExecutionStateAtom, swapExecutionStateAtom } from "@/state/swapExecutionPage";
import { TokenAndChainSelectorModal } from "@/modals/TokenAndChainSelectorModal/TokenAndChainSelectorModal";
import { SwapDetailModal } from "./SwapDetailModal";
import { SwapPageFooter } from "./SwapPageFooter";
Expand Down Expand Up @@ -58,12 +58,12 @@ export const SwapPage = () => {
const swapDetailsModal = useModal(SwapDetailModal);
const tokenAndChainSelectorModal = useModal(TokenAndChainSelectorModal);
const selectWalletmodal = useModal(WalletSelectorModal);
const setSwapExecutionState = useSetAtom(swapExecutionStateAtom);
const setCurrentPage = useSetAtom(currentPageAtom);
const setSkipBalancesRequest = useSetAtom(skipBalancesRequestAtom);
const connectedWalletModal = useModal(ConnectedWalletModal);
const sourceBalance = useSourceBalance();
const insufficientBalance = useInsufficientSourceBalance();
const setSwapExecutionState = useSetAtom(setSwapExecutionStateAtom);

const handleMaxButton = useSetMaxAmount();

Expand Down Expand Up @@ -225,7 +225,7 @@ export const SwapPage = () => {
disabled={!route}
onClick={() => {
setCurrentPage(Routes.SwapExecutionPage);
setSwapExecutionState({ userAddresses: [], route });
setSwapExecutionState();
}}
/>
);
Expand Down
37 changes: 2 additions & 35 deletions packages/widget-v2/src/state/skipClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
BalanceRequest,
} from "@skip-go/client";
import { atomWithQuery } from "jotai-tanstack-query";
import { devApiUrl, endpointOptions } from "@/constants/skipClientDefault";
import { devApiUrl, endpointOptions, prodApiUrl } from "@/constants/skipClientDefault";
import {
debouncedDestinationAssetAmountAtom,
debouncedSourceAssetAmountAtom,
Expand All @@ -30,7 +30,7 @@ import { Adapter } from "@solana/wallet-adapter-base";
import { defaultTheme, Theme } from "@/widget/theme";

export const skipClientConfigAtom = atom<SkipClientOptions>({
apiURL: devApiUrl,
apiURL: prodApiUrl,
endpointOptions,
});

Expand Down Expand Up @@ -166,39 +166,6 @@ export const skipBalancesAtom = atomWithQuery((get) => {
};
});

type SkipTransactionStatusProps = {
txsRequired: number;
txs: { chainID: string; txHash: string }[] | undefined;
};

export const skipTransactionStatusPropsAtom = atom<SkipTransactionStatusProps>({
txsRequired: 0,
txs: undefined,
});

export const skipTransactionStatus = atomWithQuery((get) => {
const skip = get(skipClient);
const { txs, txsRequired } = get(skipTransactionStatusPropsAtom);

return {
queryKey: ["skipTxStatus", txs, txsRequired],
queryFn: async () => {
if (!txs) return;

return Promise.all(
txs.map(async (tx) => {
return skip.transactionStatus({
chainID: tx.chainID,
txHash: tx.txHash,
});
})
);
},
refetchInterval: 1000 * 2,
keepPreviousData: true,
};
});

const skipRouteRequestAtom = atom<RouteRequest | undefined>((get) => {
const sourceAsset = get(sourceAssetAtom);
const destinationAsset = get(destinationAssetAtom);
Expand Down
Loading

0 comments on commit df2ba12

Please sign in to comment.