Skip to content

Commit

Permalink
Add using skipClient.balances (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
toddkao authored Sep 20, 2024
1 parent 2660924 commit daf3781
Show file tree
Hide file tree
Showing 12 changed files with 342 additions and 116 deletions.
19 changes: 14 additions & 5 deletions packages/widget-v2/src/components/AssetChainInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type AssetChainInputProps = {
selectedAsset?: AssetAtom;
priceChangePercentage?: number;
isWaitingToUpdateInputValue?: boolean;
badPriceWarning?: boolean;
};

export const AssetChainInput = ({
Expand All @@ -33,10 +34,13 @@ export const AssetChainInput = ({
handleChangeChain,
priceChangePercentage,
isWaitingToUpdateInputValue,
badPriceWarning,
}: AssetChainInputProps) => {
const theme = useTheme();
const [showPriceChangePercentage, setShowPriceChangePercentage] =
const [_showPriceChangePercentage, setShowPriceChangePercentage] =
useState(false);

const showPriceChangePercentage = _showPriceChangePercentage || badPriceWarning;
const assetDetails = useGetAssetDetails({
assetDenom: selectedAsset?.denom,
amount: value,
Expand Down Expand Up @@ -170,6 +174,7 @@ export const AssetChainInput = ({
{priceChangePercentage ? (
<Row align="center" gap={6}>
<SmallTextButton
color={badPriceWarning ? theme.error.text : undefined}
onMouseEnter={() => setShowPriceChangePercentage(true)}
onMouseLeave={() => setShowPriceChangePercentage(false)}
>
Expand All @@ -180,14 +185,16 @@ export const AssetChainInput = ({
direction={(priceChangePercentage ?? 0) > 0 ? "up" : "down"}
style={{ scale: showPriceChangePercentage ? "1" : "0.7" }}
/>
{showPriceChangePercentage && (
{(showPriceChangePercentage) && (
<SmallText color={priceChangeColor}>
{priceChangePercentage}%
</SmallText>
)}
</Row>
) : (
<SmallText>{assetDetails.formattedUsdAmount ?? 0}</SmallText>
<SmallText color={badPriceWarning ? theme.error.text : undefined}>
{assetDetails.formattedUsdAmount ?? 0}
</SmallText>
)}
{assetDetails?.chainName ? (
<GhostButton
Expand All @@ -213,15 +220,17 @@ const StyledAssetChainInputWrapper = styled(Column)`
background-color: ${(props) => props.theme.primary.background.normal};
`;

const StyledInput = styled.input <{ isWaitingToUpdateInputValue?: boolean }>`
const StyledInput = styled.input<{ isWaitingToUpdateInputValue?: boolean }>`
all: unset;
font-size: 38px;
font-weight: 300;
width: 100%;
color: ${(props) => props.theme.primary.text.normal};
background-color: ${(props) => props.theme.primary.background.normal};
${(props) => props.isWaitingToUpdateInputValue && "animation: pulse 2s cubic-bezier(.4,0,.6,1) infinite;"}
${(props) =>
props.isWaitingToUpdateInputValue &&
"animation: pulse 2s cubic-bezier(.4,0,.6,1) infinite;"}
@keyframes pulse {
0% {
opacity: 0.5;
Expand Down
2 changes: 2 additions & 0 deletions packages/widget-v2/src/components/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const SmallText = styled.p<TextProps>`
color: ${({ theme }) => theme.primary.text.lowContrast};
margin: 0;
font-size: 13px;
line-height: 13px;
${textProps}
`;

Expand All @@ -50,6 +51,7 @@ export const SmallTextButton = styled(SmallText).attrs({ as: "button" })`
export const Text = styled(SmallText)`
color: ${(props) => props.theme.primary.text.normal};
font-size: 20px;
line-height: 20px;
font-weight: 500;
${textProps}
`;
Expand Down
4 changes: 3 additions & 1 deletion packages/widget-v2/src/constants/skipClientDefault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ export const endpointOptions = {
},
};

export const apiURL = `${appUrl}/api/widget/skip`;
export const devApiUrl = "https://api.dev.skip.build";

export const prodApiUrl = `${appUrl}/api/widget/skip`;
22 changes: 21 additions & 1 deletion packages/widget-v2/src/pages/SwapPage/SwapDetailModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css, styled } from "styled-components";
import { css, styled, useTheme } from "styled-components";
import { createModal, ModalProps } from "@/components/Modal";
import { Column, Row, Spacer } from "@/components/Layout";
import { SmallText } from "@/components/Typography";
Expand All @@ -16,6 +16,7 @@ import { getBrandButtonTextColor } from "@/utils/colors";
import { QuestionMarkIcon } from "@/icons/QuestionMarkIcon";

export const SwapDetailModal = createModal((modalProps: ModalProps) => {
const theme = useTheme();
const { data: route } = useAtomValue(skipRouteAtom);
const { data: chains } = useAtomValue(skipChainsAtom);
const [swapSettings, setSwapSettings] = useAtom(swapSettingsAtom);
Expand All @@ -28,6 +29,10 @@ export const SwapDetailModal = createModal((modalProps: ModalProps) => {

const clientOperations = route && getClientOperations(route.operations);

const usesEvmInOperations = useMemo(() => {
return clientOperations?.find(operation => operation.toChainID === "1");
}, [clientOperations]);

const axelarTransferOperation = useMemo(() => {
if (!clientOperations) return;
return clientOperations?.find(
Expand Down Expand Up @@ -199,6 +204,15 @@ export const SwapDetailModal = createModal((modalProps: ModalProps) => {
</Column>
)}

{
usesEvmInOperations && <StyledEvmWarningMessage>
<SwapDetailText color={theme.warning.text}>
This swap contains at least one EVM chain, so it might take longer.
<br /> Read more about common finality times.
</SwapDetailText>
</StyledEvmWarningMessage>
}

<SwapDetailText justify="space-between">
<SwapPageFooterItems showRouteInfo />
</SwapDetailText>
Expand Down Expand Up @@ -242,6 +256,12 @@ const SwapDetailText = styled(Row).attrs({
letter-spacing: 0.26px;
`;

const StyledEvmWarningMessage = styled.div`
padding: 12px;
border-radius: 5px;
background-color: ${({ theme }) => theme.warning.background};
`;

const Tooltip = styled(SmallText).attrs({
normalTextColor: true,
})`
Expand Down
137 changes: 103 additions & 34 deletions packages/widget-v2/src/pages/SwapPage/SwapPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import { AssetChainInput } from "@/components/AssetChainInput";
import { Column, Row } from "@/components/Layout";
Expand All @@ -9,6 +9,7 @@ import {
getChainsContainingAsset,
skipChainsAtom,
skipRouteAtom,
skipBalancesRequestAtom,
} from "@/state/skipClient";
import {
sourceAssetAtom,
Expand All @@ -32,6 +33,11 @@ import { currentPageAtom, Routes } from "@/state/router";
import { GhostButton, GhostButtonProps } from "@/components/Button";
import { ConnectedWalletModal } from "@/modals/ConnectedWalletModal/ConnectedWalletModal";
import styled, { css } from "styled-components";
import {
useInsufficientSourceBalance,
useSetMaxAmount,
} from "./useSetMaxAmount";
import { useSourceBalance } from "./useSourceBalance";

export const SwapPage = () => {
const [container, setContainer] = useState<HTMLDivElement>();
Expand All @@ -42,7 +48,6 @@ export const SwapPage = () => {
const [isWaitingForNewRoute] = useAtom(isWaitingForNewRouteAtom);
const [destinationAsset, setDestinationAsset] = useAtom(destinationAssetAtom);
const [swapDirection] = useAtom(swapDirectionAtom);
const setSwapDirection = useSetAtom(swapDirectionAtom);
const [{ data: assets }] = useAtom(skipAssetsAtom);
const [{ data: chains }] = useAtom(skipChainsAtom);
const {
Expand All @@ -55,9 +60,38 @@ export const SwapPage = () => {
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 handleMaxButton = useSetMaxAmount();

const sourceAccount = useAccount(sourceAsset?.chainID);

useEffect(() => {
if (isWaitingForNewRoute) return;
if (!sourceAsset || !sourceAccount) return;
const { chainID, denom } = sourceAsset;
const { address } = sourceAccount;
if (!denom || !chainID || !address) return;

setSkipBalancesRequest({
chains: {
[chainID]: {
address,
denoms: [denom],
},
},
});
}, [
isWaitingForNewRoute,
setSkipBalancesRequest,
sourceAccount,
sourceAsset,
sourceAsset?.chainID,
]);

const sourceDetails = useGetAssetDetails({
assetDenom: sourceAsset?.denom,
amount: sourceAsset?.amount,
Expand All @@ -70,6 +104,19 @@ export const SwapPage = () => {
chainId: destinationAsset?.chainID,
});

const formattedBalance = useMemo(() => {
if (sourceBalance === undefined) return "";

const amount = sourceBalance?.amount;
let formattedBalanceAmount = sourceBalance?.formattedAmount;

if (amount === "0") {
formattedBalanceAmount = amount;
}

return `${formattedBalanceAmount} ${sourceDetails?.symbol}`;
}, [sourceBalance, sourceDetails?.symbol]);

const chainsContainingSourceAsset = useMemo(() => {
if (!chains || !assets || !sourceAsset?.symbol) return;
const result = getChainsContainingAsset(
Expand Down Expand Up @@ -158,14 +205,19 @@ export const SwapPage = () => {

const swapButton = useMemo(() => {
if (isWaitingForNewRoute) {
return <MainButton label="Finding Best Route..." loading={true} />;
return <MainButton label="Finding Best Route..." loading />;
}

if (isRouteError) {
return <MainButton label={routeError.message} disabled={true} />;
return <MainButton label={routeError.message} disabled />;
}

if (sourceAccount?.address) {
if (insufficientBalance) {
return (
<MainButton label="Insufficient balance" disabled icon={ICONS.swap} />
);
}
return (
<MainButton
label="Swap"
Expand Down Expand Up @@ -194,6 +246,7 @@ export const SwapPage = () => {
}, [
isWaitingForNewRoute,
isRouteError,
insufficientBalance,
sourceAccount?.address,
sourceAsset?.chainID,
routeError?.message,
Expand Down Expand Up @@ -237,27 +290,47 @@ export const SwapPage = () => {
}}
rightContent={
sourceAccount && (
<Row gap={6} style={{
paddingRight: 13
}}>
<TransparentButton onClick={() => {
connectedWalletModal.show();
}} style={{
padding: "8px 13px",
alignItems: "center",
gap: 8
}}>
{sourceAccount && <img style={{ objectFit: "cover" }} src={sourceAccount?.wallet.logo} height={16} width={16} />}
125 ATOM
</TransparentButton>
<TransparentButton onClick={() => {
connectedWalletModal.show();
}} style={{
padding: "8px 13px",
alignItems: "center",
}}>
Max
</TransparentButton>
<Row
gap={6}
style={{
paddingRight: 13,
}}
>
{formattedBalance && (
<>
<TransparentButton
onClick={() => {
connectedWalletModal.show();
}}
style={{
padding: "8px 13px",
alignItems: "center",
gap: 8,
}}
>
{sourceAccount && (
<img
style={{ objectFit: "cover" }}
src={sourceAccount?.wallet.logo}
height={16}
width={16}
/>
)}
{formattedBalance}
</TransparentButton>

<TransparentButton
disabled={!sourceBalance || sourceBalance?.amount === "0"}
onClick={handleMaxButton}
style={{
padding: "8px 13px",
alignItems: "center",
}}
>
Max
</TransparentButton>
</>
)}
</Row>
)
}
Expand All @@ -271,10 +344,7 @@ export const SwapPage = () => {
swapDirection === "swap-out" && isWaitingForNewRoute
}
value={sourceAsset?.amount}
onChangeValue={(newValue) => {
setSourceAssetAmount(newValue);
setSwapDirection("swap-in");
}}
onChangeValue={setSourceAssetAmount}
/>
<SwapPageBridge />
<AssetChainInput
Expand All @@ -286,15 +356,14 @@ export const SwapPage = () => {
}
value={destinationAsset?.amount}
priceChangePercentage={priceChangePercentage}
onChangeValue={(newValue) => {
setDestinationAssetAmount(newValue);
setSwapDirection("swap-out");
}}
badPriceWarning={route?.warning?.type === "BAD_PRICE_WARNING"}
onChangeValue={setDestinationAssetAmount}
/>
</Column>
{swapButton}
<SwapPageFooter
showRouteInfo
disabled={isRouteError || isWaitingForNewRoute}
onClick={() =>
swapDetailsModal.show({
drawer: true,
Expand All @@ -304,7 +373,7 @@ export const SwapPage = () => {
})
}
/>
</Column >
</Column>
<div
id="swap-flow-settings-container"
ref={(element) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/widget-v2/src/pages/SwapPage/SwapPageBridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const SwapPageBridge = () => {
const [spin, setSpin] = useState(false);
const invertSwap = useSetAtom(invertSwapAtom);
const onInvertSwap = () => {
invertSwap("swap-out");
invertSwap();

let spinTimeout = undefined;
clearTimeout(spinTimeout);
Expand Down
Loading

0 comments on commit daf3781

Please sign in to comment.