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(extension) add FOOR buy ADA button to Banxa [LW-5104],[LW-10213] #1016

Merged
merged 22 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d6045aa
feat(extension): add buy ADA button and modal (WIP)
tommayeliog Apr 2, 2024
6f67288
feat(extension): add buy ADA button and modal - scrollbar
tommayeliog Apr 2, 2024
348f1bc
feat(extension): add buy ADA button and modal .env vars
tommayeliog Apr 3, 2024
709be6f
feat(extension): buy ADA Banxa - fix PR comments
tommayeliog Apr 4, 2024
c3f1bc7
Merge branch 'main' into feat/LW-5104-foor-buy-ada-button-modal
tommayeliog Apr 4, 2024
24cd31f
feat(extension): add PostHog events for Topup buy ADA
tommayeliog Apr 5, 2024
1b9d076
Merge branch 'main' into feat/LW-5104-foor-buy-ada-button-modal
tommayeliog Apr 8, 2024
02f5b6d
fix(extension): remove unnecessary PostHog action
tommayeliog Apr 8, 2024
ff1355d
Merge branch 'main' into feat/LW-5104-foor-buy-ada-button-modal
tommayeliog Apr 8, 2024
480dd6f
refactor(extension): rename component for TopUpWallet
tommayeliog Apr 8, 2024
e481499
Merge branch 'main' into feat/LW-5104-foor-buy-ada-button-modal
tommayeliog May 9, 2024
7e88172
feat(extension): foor buy ada via Banxa
tommayeliog May 10, 2024
0f4a8e2
feat(extension): fix darkmode colour
tommayeliog May 10, 2024
7d98bf6
feat(extension): fixing UI for Buy ADA card
tommayeliog May 15, 2024
1de8843
feat(extension): remove Buy ADA card from popup sidebar on smaller re…
tommayeliog May 15, 2024
f217d20
feat(extension): show buy ADA only on Mainnet
tommayeliog May 15, 2024
38da05f
feat(extension): by Ada Dialog - set default button Continue
tommayeliog May 15, 2024
1749dd7
refactor(extension): fix test for AssetsPortfolio
tommayeliog May 16, 2024
40145ee
Merge branch 'main' into feat/LW-5104-foor-buy-ada-button-modal
tommayeliog May 20, 2024
e314271
fix(ui): fix storybook call to action button
tommayeliog May 20, 2024
6c0d6d9
Update apps/browser-extension-wallet/src/views/browser-view/component…
tommayeliog May 20, 2024
a356d56
Update apps/browser-extension-wallet/src/views/browser-view/component…
tommayeliog May 20, 2024
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
3 changes: 3 additions & 0 deletions apps/browser-extension-wallet/.env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ USE_MULTI_DELEGATION_STAKING_ACTIVITY=true
USE_MULTI_DELEGATION_STAKING_GRID_VIEW=true
USE_MULTI_DELEGATION_STAKING_FILTERS=false
USE_ROS_STAKING_COLUMN=false
USE_FOOR_TOPUP=false

USE_POSTHOG_ANALYTICS_FOR_OPTED_OUT=false
USE_MULTI_WALLET=true
Expand All @@ -48,6 +49,8 @@ PRIVACY_POLICY_URL=https://www.lace.io/iog-privacy-policy.pdf
COOKIE_POLICY_URL=https://www.lace.io/lace-cookie-policy.pdf
TERMS_OF_USE_URL=https://www.lace.io/lace-terms-of-use.pdf
YOUTUBE_RECOVERY_PHRASE_VIDEO_URL=https://www.youtube-nocookie.com/embed/hOFVXo969rk?si=0a-hNDVME6eTboIX
BANXA_LACE_URL=https://lacewallet.banxa-sandbox.com/
BANXA_HOMEPAGE_URL=https://banxa.com/

# events tracking
PUBLIC_POSTHOG_HOST=https://eu.posthog.com
Expand Down
3 changes: 3 additions & 0 deletions apps/browser-extension-wallet/.env.developerpreview
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ USE_MULTI_DELEGATION_STAKING_TREZOR=false
USE_MULTI_DELEGATION_STAKING_ACTIVITY=true
USE_MULTI_DELEGATION_STAKING_GRID_VIEW=true
USE_ROS_STAKING_COLUMN=false
USE_FOOR_TOPUP=false

USE_POSTHOG_ANALYTICS_FOR_OPTED_OUT=false
USE_MULTI_WALLET=false
Expand All @@ -48,6 +49,8 @@ PRIVACY_POLICY_URL=https://www.lace.io/iog-privacy-policy.pdf
COOKIE_POLICY_URL=https://www.lace.io/lace-cookie-policy.pdf
TERMS_OF_USE_URL=https://www.lace.io/lace-terms-of-use.pdf
YOUTUBE_RECOVERY_PHRASE_VIDEO_URL=https://www.youtube-nocookie.com/embed/hOFVXo969rk?si=0a-hNDVME6eTboIX
BANXA_LACE_URL=https://lacewallet.banxa-sandbox.com/
BANXA_HOMEPAGE_URL=https://banxa.com/

# events tracking
PUBLIC_POSTHOG_HOST=https://eu.posthog.com
Expand Down
3 changes: 3 additions & 0 deletions apps/browser-extension-wallet/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ USE_MULTI_DELEGATION_STAKING_ACTIVITY=true
USE_MULTI_DELEGATION_STAKING_GRID_VIEW=true
USE_MULTI_DELEGATION_STAKING_FILTERS=false
USE_ROS_STAKING_COLUMN=false
USE_FOOR_TOPUP=false

# In App URLs
CATALYST_GOOGLE_PLAY_URL=https://play.google.com/store/apps/details?id=io.iohk.vitvoting
Expand All @@ -44,6 +45,8 @@ PRIVACY_POLICY_URL=https://www.lace.io/iog-privacy-policy.pdf
COOKIE_POLICY_URL=https://www.lace.io/lace-cookie-policy.pdf
TERMS_OF_USE_URL=https://www.lace.io/lace-terms-of-use.pdf
YOUTUBE_RECOVERY_PHRASE_VIDEO_URL=https://www.youtube-nocookie.com/embed/hOFVXo969rk?si=0a-hNDVME6eTboIX
BANXA_LACE_URL=https://lacewallet.banxa-sandbox.com/
BANXA_HOMEPAGE_URL=https://banxa.com/
# events tracking
PUBLIC_POSTHOG_HOST=https://eu.posthog.com
# set this variable to true only in release packages. By having this set to false, we ensure that we will not be using Post Hog production projects tokens in development stage
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@import '../../../../../../../packages/common/src/ui/styles/abstracts/mixins';

.card {
align-self: stretch;
}

.titleBadge {
align-self: start;
border-radius: size_unit(2);
background: var(--primary-gradient);
display: flex;
align-items: center;
justify-content: center;
padding: 0 size_unit(1);
height: 20px;
}
.badgeCaption {
color: var(--color-white, #fff) !important;
}

.scroll {
@include scroll-bar-style;
overflow: auto;
height: 127px;
padding: 0 4px;
color: var(--light-mode-dark-grey, var(--dark-mode-light-grey, #6f7786));
}

.disclaimerShort {
color: var(--light-mode-mid-grey, var(--dark-mode-light-grey, #c0c0c0)) !important;
}

.disclaimerFullWrapper {
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { tabs } from 'webextension-polyfill';
import { ReactComponent as AdaComponentTransparent } from '@lace/icons/dist/AdaComponentTransparent';
import React, { useRef, useState } from 'react';
import { Button } from '@lace/ui';
import { TopUpWalletDialog } from './TopUpWalletDialog';
import { useTranslation } from 'react-i18next';
import { BANXA_LACE_URL } from './config';
import { useAnalyticsContext } from '@providers';
import { PostHogAction } from '@lace/common';

export const TopUpWalletButton = (): React.ReactElement => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a button? Maybe we could leave TopUpWallet as a name because it's a feature with a button and dialog. You can come up with a better name ofc 😄

On the other hand I'd probably leave the button/dialog separately and integrate the logic in some sort of TopUpWalletCardContainer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @przemyslaw-wlodek, yes, it's a button and a modal. It's not stated on the JIRA ticket but maybe at some point a new requirement will be added for the modal to be visible just once. Then Button will be much more relevant. TBO I don't know - maybe TopUpWalletButtonConfirmation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider TopUpWallet then 😃 WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @przemyslaw-wlodek, I'm not 100% sure :) but it just because the feature has been named with the same name (TopUpWallet), and this "button + modal" is just one of the components, however I'm happy to rename it.

const dialogTriggerReference = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState(false);
const { t } = useTranslation();
const analytics = useAnalyticsContext();

return (
<>
<Button.CallToAction
icon={<AdaComponentTransparent />}
label={t('browserView.assets.topupWallet.buyButton.caption')}
onClick={() => {
analytics.sendEventToPostHog(PostHogAction.TokenTokensTopYourWalletBuyAdaClick);
setOpen(true);
}}
ref={dialogTriggerReference}
/>

<TopUpWalletDialog
onCancel={() => {
analytics.sendEventToPostHog(PostHogAction.TokenBuyAdaDisclaimerGoBackClick);
setOpen(false);
}}
open={open}
triggerRef={dialogTriggerReference}
onConfirm={() => {
analytics.sendEventToPostHog(PostHogAction.TokenBuyAdaDisclaimerContinueClick);
tabs.create({ url: BANXA_LACE_URL });
setOpen(false);
}}
/>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Card, Flex, Text } from '@lace/ui';
import styles from './TopUpWallet.module.scss';
import { useTranslation } from 'react-i18next';
import { TopUpWalletButton } from './TopUpWalletButton';

export const TopUpWalletCard = (): React.ReactElement => {
const { t } = useTranslation();

return (
<Card.Outlined className={styles.card}>
<Flex flexDirection="column" mx="$20" my="$20" gap="$6" alignItems="stretch">
<div className={styles.titleBadge}>
<Text.Label className={styles.badgeCaption} weight="$medium">
{t('browserView.assets.topupWallet.card.badge')}
</Text.Label>
</div>
<Flex my="$10">
<Text.SubHeading weight="$bold">{t('browserView.assets.topupWallet.card.title')}</Text.SubHeading>
</Flex>
<Flex flexDirection="column" alignItems="stretch" gap="$16" mt="$10">
<Text.Body.Normal weight="$medium" color="secondary">
{t('browserView.assets.topupWallet.buyButton.title')}
</Text.Body.Normal>
<TopUpWalletButton />
<Text.Label weight="$medium" className={styles.disclaimerShort}>
{t('browserView.assets.topupWallet.disclaimer.short')}
</Text.Label>
</Flex>
</Flex>
</Card.Outlined>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useCallback } from 'react';
import { Box, Dialog, Text, TextLink } from '@lace/ui';
import styles from './TopUpWallet.module.scss';
import { useTranslation } from 'react-i18next';
import { tabs } from 'webextension-polyfill';
import { BANXA_HOMEPAGE_URL } from './config';

interface TopUpWalletDialogProps {
open: boolean;
onCancel: () => void;
onConfirm: () => void;
triggerRef: React.RefObject<HTMLElement>;
}
export const TopUpWalletDialog = ({
open,
onCancel,
onConfirm,
triggerRef
}: TopUpWalletDialogProps): React.ReactElement => {
const { t } = useTranslation();
const handleOpenTabBanxaHomepage = useCallback(() => {
tabs.create({ url: BANXA_HOMEPAGE_URL });
}, []);

return (
<Dialog.Root open={open} setOpen={onCancel} zIndex={1000} onCloseAutoFocusRef={triggerRef}>
<Dialog.Title>{t('browserView.assets.topupWallet.modal.title')}</Dialog.Title>
<Dialog.Description>
<Box className={styles.disclaimerFullWrapper}>
<Text.Body.Normal weight="$medium" color="secondary">
{t('browserView.assets.topupWallet.disclaimer.full.part1')}
</Text.Body.Normal>
<TextLink
onClick={handleOpenTabBanxaHomepage}
label={t('browserView.assets.topupWallet.disclaimer.full.banxaLinkCaption')}
/>
<Text.Body.Normal weight="$medium" color="secondary">
{t('browserView.assets.topupWallet.disclaimer.full.part2')}
</Text.Body.Normal>
<TextLink
onClick={handleOpenTabBanxaHomepage}
label={t('browserView.assets.topupWallet.disclaimer.full.banxaLinkCaption')}
/>
</Box>
</Dialog.Description>
<Dialog.Actions>
<Dialog.Action cancel label={t('browserView.assets.topupWallet.modal.goBack')} onClick={onCancel} />
<Dialog.Action autoFocus label={t('browserView.assets.topupWallet.modal.continue')} onClick={onConfirm} />
</Dialog.Actions>
</Dialog.Root>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const USE_FOOR_TOPUP = process.env.USE_FOOR_TOPUP === 'true';
export const BANXA_LACE_URL = process.env.BANXA_LACE_URL;
export const BANXA_HOMEPAGE_URL = process.env.BANXA_HOMEPAGE_URL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './TopUpWalletButton';
export * from './TopUpWalletCard';
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from './SideMenu';
export * from './WarningModal';
export * from './SocialNetworks';
export * from './WalletUsedAddressesDrawer';
export * from './TopUpWallet';
export * from './EmptySearch';
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { useBalances, useFetchCoinPrice, useRedirection } from '@hooks';
import { useWalletStore } from '@src/stores';
import { useCurrencyStore } from '@providers/currency';
import { cardanoTransformer, assetTransformer } from '@src/utils/assets-transformers';
import { SectionLayout, Layout } from '@src/views/browser-view/components';
import { SectionLayout, Layout, TopUpWalletCard } from '@src/views/browser-view/components';
import { useDrawer } from '@src/views/browser-view/stores';
import { DrawerContent } from '@src/views/browser-view/components/Drawer';
import { walletRoutePaths } from '@routes';
import { APP_MODE_POPUP } from '@src/utils/constants';
import { ContentLayout } from '@components/Layout';
import { useAnalyticsContext } from '@providers';
import { useAnalyticsContext, useAppSettingsContext } from '@providers';
import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker';
import { isNFT } from '@src/utils/is-nft';
import {
Expand All @@ -27,6 +27,10 @@ import { AssetsPortfolio } from './AssetsPortfolio/AssetsPortfolio';
import { AssetDetailsDrawer } from './AssetDetailsDrawer/AssetDetailsDrawer';
import { AssetActivityDetails } from './AssetActivityDetails/AssetActivityDetails';
import { AssetEducationalList } from './AssetEducationalList/AssetEducationalList';
import { Flex } from '@lace/ui';
import { USE_FOOR_TOPUP } from '@src/views/browser-view/components/TopUpWallet/config';
import { useIsSmallerScreenWidthThan } from '@hooks/useIsSmallerScreenWidthThan';
import { BREAKPOINT_SMALL } from '@src/styles/constants';

const LIST_CHUNK_SIZE = 12;
const SEND_COIN_OUTPUT_ID = 'output1';
Expand Down Expand Up @@ -57,6 +61,9 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => {
const hiddenBalancePlaceholder = getHiddenBalancePlaceholder();
const { setPickedCoin } = useCoinStateSelector(SEND_COIN_OUTPUT_ID);
const { setTriggerPoint } = useAnalyticsSendFlowTriggerPoint();
const isScreenTooSmallForSidePanel = useIsSmallerScreenWidthThan(BREAKPOINT_SMALL);
const [{ chainName }] = useAppSettingsContext();
const isMainnet = chainName === 'Mainnet';

const [isActivityDetailsOpen, setIsActivityDetailsOpen] = useState(false);
const [fullAssetList, setFullAssetList] = useState<AssetTableProps['rows']>();
Expand Down Expand Up @@ -307,7 +314,15 @@ export const Assets = ({ topSection }: AssetsProps): React.ReactElement => {
</>
) : (
<Layout>
<SectionLayout hasCredit={fullAssetList?.length > 0} sidePanelContent={<AssetEducationalList />}>
<SectionLayout
hasCredit={fullAssetList?.length > 0}
sidePanelContent={
<Flex flexDirection="column" gap="$28">
{USE_FOOR_TOPUP && isMainnet && !isScreenTooSmallForSidePanel && <TopUpWalletCard />}
<AssetEducationalList />
</Flex>
}
>
{topSection}
{assetsPortfolio}
{drawers}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
}

.portfolio {
margin-bottom: size_unit(5);
margin-bottom: size_unit(2);
}

.testPopupClass {
Expand All @@ -19,3 +19,7 @@
margin-top: size_unit(3);
}
}

.topupWalletDisclaimerShort {
color: var(--light-mode-mid-grey, var(--dark-mode-light-grey, #c0c0c0)) !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IRow, SendReceive } from '@lace/core';
import { SectionTitle } from '@components/Layout/SectionTitle';
import { APP_MODE_POPUP, AppMode } from '@src/utils/constants';
import { compactNumberWithUnit } from '@src/utils/format-number';
import { PortfolioBalance } from '@src/views/browser-view/components';
import { PortfolioBalance, TopUpWalletButton } from '@src/views/browser-view/components';
import { useCurrencyStore } from '@providers/currency';
import { useWalletStore } from '@src/stores';
import { useFetchCoinPrice } from '@hooks/useFetchCoinPrice';
Expand All @@ -19,6 +19,12 @@ import BigNumber from 'bignumber.js';
import { SendFlowTriggerPoints } from '../../../send-transaction';
import { AssetPortfolioContent } from './AssetPortfolioContent';

import { useIsSmallerScreenWidthThan } from '@hooks/useIsSmallerScreenWidthThan';
import { BREAKPOINT_SMALL } from '@src/styles/constants';
import { USE_FOOR_TOPUP } from '@src/views/browser-view/components/TopUpWallet/config';
import { Flex, Text } from '@lace/ui';
import { Wallet } from '@lace/cardano';

const MINUTES_UNTIL_WARNING_BANNER = 3;

export interface AssetsPortfolioProps {
Expand Down Expand Up @@ -49,13 +55,16 @@ export const AssetsPortfolio = ({
const analytics = useAnalyticsContext();
const { t } = useTranslation();
const {
walletUI: { canManageBalancesVisibility, areBalancesVisible }
walletUI: { canManageBalancesVisibility, areBalancesVisible },
currentChain
} = useWalletStore();
const { fiatCurrency } = useCurrencyStore();
const redirectToReceive = useRedirection(walletRoutePaths.receive);
const redirectToSend = useRedirection<{ params: { id: string } }>(walletRoutePaths.send);
const isScreenTooSmallForSidePanel = useIsSmallerScreenWidthThan(BREAKPOINT_SMALL);

const isPopupView = appMode === APP_MODE_POPUP;
const isMainnet = currentChain?.networkMagic === Wallet.Cardano.NetworkMagics.Mainnet;

const portfolioBalanceAsBigNumber = useMemo(() => new BigNumber(portfolioTotalBalance), [portfolioTotalBalance]);
const isPortfolioBalanceLoading = useMemo(
Expand Down Expand Up @@ -117,6 +126,19 @@ export const AssetsPortfolio = ({
}}
/>
)}
{!isPopupView && isScreenTooSmallForSidePanel && USE_FOOR_TOPUP && isMainnet && (
<Flex flexDirection="column" gap="$10" mb="$16">
<Text.Body.Normal weight="$medium" color="secondary">
{t('browserView.assets.topupWallet.buyButton.title')}
</Text.Body.Normal>
<Flex flexDirection="column" alignItems="stretch" w="$294">
<TopUpWalletButton />
</Flex>
<Text.Label weight="$medium" className={styles.topupWalletDisclaimerShort}>
{t('browserView.assets.topupWallet.disclaimer.short')}
</Text.Label>
</Flex>
)}
<AssetPortfolioContent
totalAssets={totalAssets}
assetList={assetList}
Expand Down
5 changes: 4 additions & 1 deletion packages/common/src/analytics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export enum PostHogAction {
StakingBrowsePoolsMoreOptionsSortingLiveStakeClick = 'staking | browse pools | more options sorting | live-stake | click',
StakingBrowsePoolsTickerClick = 'staking | browse pools | ticker | click',
StakingBrowsePoolsSaturationClick = 'staking | browse pools | saturation | click',
StakingBrowsePoolsROSClick = 'staking | browse pools | ros | click',
StakingBrowsePoolsCostClick = 'staking | browse pools | cost | click',
StakingBrowsePoolsMarginClick = 'staking | browse pools | margin | click',
StakingBrowsePoolsProducedBlocksClick = 'staking | browse pools | produced blocks | click',
Expand Down Expand Up @@ -248,6 +247,10 @@ export enum PostHogAction {
TokenTokensTokenRowClick = 'token | tokens | token row | click',
TokenTokenDetailViewAllClick = 'token | token detail | view all | click',
TokenTokenDetailXClick = 'token | token detail | x | click',
TokenTokensTopYourWalletBuyAdaClick = 'token | tokens | top your wallet | buy ada | click',
TokenBuyAdaDisclaimerGoBackClick = 'token | buy ada | disclaimer | go back | click',
TokenBuyAdaDisclaimerAgreeClick = 'token | buy ada | disclaimer | agree | click',
TokenBuyAdaDisclaimerContinueClick = 'token | buy ada | disclaimer | continue | click',
// Activities
ActivityActivityClick = 'activity | activity | click',
ActivityActivityActivityRowClick = 'activity | activity | activity row | click',
Expand Down
3 changes: 3 additions & 0 deletions packages/icons/raw/ada.component-transparent.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading