Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: stacks ft fiat values from alex-sdk #5151

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StacksFungibleTokenAsset } from '@shared/models/crypto-asset.model';
import { createMoney } from '@shared/models/money.model';

import {
isFtNameLikeStx,
Expand Down Expand Up @@ -31,6 +32,7 @@ describe(isTransferableStacksFungibleTokenAsset.name, () => {
canTransfer: true,
hasMemo: true,
imageCanonicalUri: '',
price: createMoney(0, 'USD'),
symbol: 'CAT',
};
expect(isTransferableStacksFungibleTokenAsset(asset)).toBeTruthy();
Expand All @@ -47,6 +49,7 @@ describe(isTransferableStacksFungibleTokenAsset.name, () => {
canTransfer: true,
hasMemo: true,
imageCanonicalUri: '',
price: createMoney(0, 'USD'),
symbol: 'CAT',
};
expect(isTransferableStacksFungibleTokenAsset(asset)).toBeTruthy();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Money, createMoney } from '@shared/models/money.model';
import { type Money, createMoney } from '@shared/models/money.model';
import { isUndefined } from '@shared/utils';

import { useConvertAlexSdkCurrencyToFiatAmount } from '@app/common/hooks/use-convert-to-fiat-amount';
Expand All @@ -7,32 +7,32 @@ import { unitToFractionalUnit } from '@app/common/money/unit-conversion';

export function useAlexSdkAmountAsFiat(balance?: Money, price?: Money, value?: string) {
const convertAlexSdkCurrencyToUsd = useConvertAlexSdkCurrencyToFiatAmount(
// @ts-expect-error TODO: balance?.symbol should be of a Cryptocurrency type.
balance?.symbol ?? '',
price ?? createMoney(0, 'USD')
);

if (isUndefined(balance) || isUndefined(price) || isUndefined(value)) return '';
if (isUndefined(balance) || isUndefined(price) || isUndefined(value)) return;

const convertedAmountAsMoney = convertAlexSdkCurrencyToUsd(
createMoney(unitToFractionalUnit(balance.decimals)(value), balance.symbol, balance.decimals)
);

return convertedAmountAsMoney.amount.isNaN() ? '' : i18nFormatCurrency(convertedAmountAsMoney);
if (convertedAmountAsMoney.amount.isNaN()) return;
return i18nFormatCurrency(convertedAmountAsMoney);
}

export function useAlexSdkBalanceAsFiat(balance?: Money, price?: Money) {
export function useAlexSdkBalanceAsFiat(balance: Money, price?: Money | null) {
const convertAlexSdkCurrencyToUsd = useConvertAlexSdkCurrencyToFiatAmount(
// @ts-expect-error TODO: balance?.symbol should be of a Cryptocurrency type.
balance?.symbol ?? '',
balance.symbol,
price ?? createMoney(0, 'USD')
);

if (isUndefined(balance) || isUndefined(price)) return '';
if (isUndefined(balance) || isUndefined(price)) return;

const convertedBalanceAsMoney = convertAlexSdkCurrencyToUsd(
createMoney(balance.amount, balance.symbol, balance.decimals)
);

return convertedBalanceAsMoney.amount.isNaN() ? '' : i18nFormatCurrency(convertedBalanceAsMoney);
if (convertedBalanceAsMoney.amount.isNaN() || convertedBalanceAsMoney.amount.isEqualTo(0)) return;
return i18nFormatCurrency(convertedBalanceAsMoney);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { styled } from 'leather-styles/jsx';

import { StacksFungibleTokenAssetBalance } from '@shared/models/crypto-asset-balance.model';

import { useAlexSdkBalanceAsFiat } from '@app/common/hooks/use-alex-sdk';
import { StacksAssetAvatar } from '@app/components/crypto-assets/stacks/components/stacks-asset-avatar';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
Expand All @@ -17,6 +18,7 @@ export function StacksFungibleTokenAssetItemLayout({
assetBalance,
onClick,
}: StacksFungibleTokenAssetItemLayoutProps) {
const balanceAsFiat = useAlexSdkBalanceAsFiat(assetBalance.balance, assetBalance.asset.price);
const { amount, avatar, caption, dataTestId, formattedBalance, imageCanonicalUri, title } =
parseStacksFungibleTokenAssetBalance(assetBalance);

Expand Down Expand Up @@ -45,6 +47,7 @@ export function StacksFungibleTokenAssetItemLayout({
</styled.span>
</BasicTooltip>
}
captionRight={balanceAsFiat}
/>
</Pressable>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ interface StacksBalanceListItemProps {
address: string;
}
export function StacksBalanceListItem({ address }: StacksBalanceListItemProps) {
const balaceDetails = useStxBalance();
const balanceDetails = useStxBalance();
return (
<StacksBalanceListItemLayout
address={address}
isInitialLoading={balaceDetails.stxBalanceQuery.isInitialLoading}
{...balaceDetails}
isInitialLoading={balanceDetails.stxBalanceQuery.isInitialLoading}
{...balanceDetails}
/>
);
}
25 changes: 7 additions & 18 deletions src/app/pages/fund/components/fund.layout.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { Stack, styled } from 'leather-styles/jsx';

import type { Blockchains } from '@shared/models/blockchain.model';
import { CryptoCurrencies } from '@shared/models/currencies.model';

import { HasChildren } from '@app/common/has-children';

const nameMap: Record<CryptoCurrencies, { name: string; symbol: string }> = {
BTC: {
name: 'Bitcoin',
symbol: 'BTC',
},
STX: {
name: 'Stacks',
symbol: 'STX',
},
};

interface FundLayoutProps extends HasChildren {
blockchain: Blockchains;
symbol: CryptoCurrencies;
}

export function FundLayout({ symbol, children }: FundLayoutProps) {
const name = nameMap[symbol].name;
const nameAbbr = nameMap[symbol].symbol;
export function FundLayout({ blockchain, symbol, children }: FundLayoutProps) {
return (
<Stack
alignItems={{ base: 'left', md: 'center' }}
Expand All @@ -44,9 +32,10 @@ export function FundLayout({ symbol, children }: FundLayoutProps) {
maxWidth="544px"
textAlign={{ base: 'left', md: 'center' }}
>
Choose an exchange to fund your account with {name} ({nameAbbr}) or deposit from elsewhere.
Exchanges with “Fast checkout” make it easier to purchase {nameAbbr} for direct deposit into
your wallet with a credit card.
Choose an exchange to fund your account with{' '}
<styled.span textTransform="capitalize">{blockchain}</styled.span> ({symbol}) or deposit
from elsewhere. Exchanges with “Fast checkout” make it easier to purchase {symbol} for
direct deposit into your wallet with a credit card.
</styled.span>
{children}
</Stack>
Expand Down
16 changes: 3 additions & 13 deletions src/app/pages/fund/fiat-providers-list.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useMemo } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

import { Grid } from 'leather-styles/jsx';

import { CryptoCurrencies } from '@shared/models/currencies.model';
import { RouteUrls } from '@shared/route-urls';

import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
Expand All @@ -20,25 +18,17 @@ import { ReceiveFundsItem } from './components/receive-funds-item';

interface FiatProvidersProps {
address: string;
route: string;
symbol: CryptoCurrencies;
}
export function FiatProvidersList(props: FiatProvidersProps) {
const { address, symbol } = props;
const { address, route, symbol } = props;
const navigate = useNavigate();
const activeProviders = useActiveFiatProviders();
const hasProviders = useHasFiatProviders();
const analytics = useAnalytics();
const location = useLocation();

const routeToQr = useMemo(() => {
switch (symbol) {
case 'BTC':
return RouteUrls.ReceiveBtc;
case 'STX':
return RouteUrls.ReceiveStx;
}
}, [symbol]);

const goToProviderExternalWebsite = (provider: string, providerUrl: string) => {
void analytics.track('select_buy_option', { provider });
openInNewTab(providerUrl);
Expand All @@ -56,7 +46,7 @@ export function FiatProvidersList(props: FiatProvidersProps) {
<ReceiveFundsItem
symbol={symbol}
onReceive={() =>
navigate(routeToQr, {
navigate(route, {
state: { backgroundLocation: location },
})
}
Expand Down
70 changes: 39 additions & 31 deletions src/app/pages/fund/fund.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Outlet, useParams } from 'react-router-dom';

import { isCryptoCurrency } from '@shared/models/currencies.model';
import type { Blockchains } from '@shared/models/blockchain.model';
import type {
BitcoinCryptoCurrencyAssetBalance,
StacksCryptoCurrencyAssetBalance,
} from '@shared/models/crypto-asset-balance.model';
import type { CryptoCurrencies } from '@shared/models/currencies.model';
import { RouteUrls } from '@shared/route-urls';

import { useBtcCryptoCurrencyAssetBalance } from '@app/common/hooks/balance/btc/use-btc-crypto-currency-asset-balance';
import { useStxCryptoCurrencyAssetBalance } from '@app/common/hooks/balance/stx/use-stx-crypto-currency-asset-balance';
Expand All @@ -11,45 +17,47 @@ import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/s
import { FundLayout } from './components/fund.layout';
import { FiatProvidersList } from './fiat-providers-list';

interface FundCryptoCurrencyInfo {
address?: string;
balance?: BitcoinCryptoCurrencyAssetBalance | StacksCryptoCurrencyAssetBalance;
blockchain: Blockchains;
route: string;
symbol: CryptoCurrencies;
}

export function FundPage() {
const currentStxAccount = useCurrentStacksAccount();
const bitcoinSigner = useCurrentAccountNativeSegwitIndexZeroSignerNullable();
const btcCryptoCurrencyAssetBalance = useBtcCryptoCurrencyAssetBalance();
const stxCryptoCurrencyAssetBalance = useStxCryptoCurrencyAssetBalance();
const { currency } = useParams();

function getSymbol() {
if (isCryptoCurrency(currency)) {
return currency;
}
return 'STX';
}
function getAddress() {
switch (symbol) {
case 'BTC':
return bitcoinSigner?.address;
case 'STX':
return currentStxAccount?.address;
}
}
function getBalance() {
switch (symbol) {
case 'BTC':
return btcCryptoCurrencyAssetBalance;
case 'STX':
return stxCryptoCurrencyAssetBalance;
}
}

const symbol = getSymbol();
const address = getAddress();
const balance = getBalance();
const { currency = 'STX' } = useParams();

const fundCryptoCurrencyMap: Record<CryptoCurrencies, FundCryptoCurrencyInfo> = {
BTC: {
address: bitcoinSigner?.address,
balance: btcCryptoCurrencyAssetBalance?.btcBalance,
blockchain: 'Bitcoin',
route: RouteUrls.ReceiveBtc,
symbol: currency,
},
STX: {
address: currentStxAccount?.address,
balance: stxCryptoCurrencyAssetBalance,
blockchain: 'Stacks',
route: RouteUrls.ReceiveStx,
symbol: currency,
},
};

const { address, balance, blockchain, route, symbol } =
fundCryptoCurrencyMap[currency as CryptoCurrencies];

if (!address || !balance) return <FullPageLoadingSpinner />;

return (
<>
<FundLayout symbol={symbol}>
<FiatProvidersList address={address} symbol={symbol} />
<FundLayout blockchain={blockchain} symbol={symbol}>
<FiatProvidersList address={address} route={route} symbol={symbol} />
</FundLayout>
<Outlet />
</>
Expand Down
10 changes: 5 additions & 5 deletions src/app/pages/swap/alex-swap-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import BigNumber from 'bignumber.js';
import { logger } from '@shared/logger';
import { RouteUrls } from '@shared/route-urls';
import { isDefined, isUndefined } from '@shared/utils';
import { alex } from '@shared/utils/alex-sdk';

import { LoadingKeys, useLoading } from '@app/common/hooks/use-loading';
import { useWalletType } from '@app/common/use-wallet-type';
Expand Down Expand Up @@ -55,7 +56,6 @@ function AlexSwapContainer() {
});

const {
alexSDK,
fetchToAmount,
createSwapAssetFromAlexCurrency,
isFetchingExchangeRate,
Expand All @@ -66,7 +66,7 @@ function AlexSwapContainer() {
swapSubmissionData,
} = useAlexSwap();

const broadcastAlexSwap = useAlexBroadcastSwap(alexSDK);
const broadcastAlexSwap = useAlexBroadcastSwap();
const broadcastStacksSwap = useStacksBroadcastSwap();

const swappableAssets: SwapAsset[] = useMemo(
Expand All @@ -84,8 +84,8 @@ function AlexSwapContainer() {
}

const [router, lpFee] = await Promise.all([
alexSDK.getRouter(values.swapAssetFrom.currency, values.swapAssetTo.currency),
alexSDK.getFeeRate(values.swapAssetFrom.currency, values.swapAssetTo.currency),
alex.getRouter(values.swapAssetFrom.currency, values.swapAssetTo.currency),
alex.getFeeRate(values.swapAssetFrom.currency, values.swapAssetTo.currency),
]);

onSetSwapSubmissionData({
Expand Down Expand Up @@ -141,7 +141,7 @@ function AlexSwapContainer() {
.toString()
);

const tx = alexSDK.runSwap(
const tx = alex.runSwap(
currentAccount?.address,
swapSubmissionData.swapAssetFrom.currency,
swapSubmissionData.swapAssetTo.currency,
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/swap/components/swap-amount-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function getPlaceholderValue(name: string, values: SwapFormValues) {
}

interface SwapAmountFieldProps {
amountAsFiat: string;
amountAsFiat?: string;
isDisabled?: boolean;
name: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { SwapSelectors } from '@tests/selectors/swap.selectors';

import { useAlexSdkBalanceAsFiat } from '@app/common/hooks/use-alex-sdk';
import { formatMoneyWithoutSymbol } from '@app/common/money/format-money';
import type { SwapAsset } from '@app/pages/swap/hooks/use-swap-form';
import { useGetFungibleTokenMetadataQuery } from '@app/query/stacks/tokens/fungible-tokens/fungible-token-metadata.query';
import { isFtAsset } from '@app/query/stacks/tokens/token-metadata.utils';
import { Avatar, defaultFallbackDelay, getAvatarFallback } from '@app/ui/components/avatar/avatar';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/pressable/pressable';

import { useAlexSdkBalanceAsFiat } from '../../../hooks/use-alex-sdk-fiat-price';
import { SwapAsset } from '../../../hooks/use-swap-form';

interface SwapAssetItemProps {
asset: SwapAsset;
onClick(): void;
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/swap/components/swap-selected-asset-from.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { createMoney } from '@shared/models/money.model';
import { isUndefined } from '@shared/utils';

import { useShowFieldError } from '@app/common/form-utils';
import { useAlexSdkAmountAsFiat } from '@app/common/hooks/use-alex-sdk';
import { convertAmountToFractionalUnit } from '@app/common/money/calculate-money';
import { formatMoneyWithoutSymbol } from '@app/common/money/format-money';

import { useAlexSdkAmountAsFiat } from '../hooks/use-alex-sdk-fiat-price';
import { SwapFormValues } from '../hooks/use-swap-form';
import { useSwapContext } from '../swap.context';
import { SwapAmountField } from './swap-amount-field';
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/swap/components/swap-selected-asset-to.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useField } from 'formik';

import { useAlexSdkAmountAsFiat } from '@app/common/hooks/use-alex-sdk';
import { formatMoneyWithoutSymbol } from '@app/common/money/format-money';
import { LoadingSpinner } from '@app/components/loading-spinner';

import { useAlexSdkAmountAsFiat } from '../hooks/use-alex-sdk-fiat-price';
import { useSwapContext } from '../swap.context';
import { SwapAmountField } from './swap-amount-field';
import { SwapSelectedAssetLayout } from './swap-selected-asset.layout';
Expand Down
Loading
Loading