From 3360f0cd7a873266c63b021f612e9795e7593b07 Mon Sep 17 00:00:00 2001
From: Pete Watters <2938440+pete-watters@users.noreply.github.com>
Date: Tue, 16 Apr 2024 06:41:48 +0100
Subject: [PATCH] chore: add BRC-20 and SRC-20 to collectibles
---
src/app/common/utils/sort-assets-by-symbol.ts | 23 +++++
.../components/receive-collectibles.tsx | 4 +-
.../receive/components/receive-tokens.tsx | 86 ++++++++++++++++++-
src/app/pages/receive/receive-dialog.tsx | 33 ++++---
tests/page-object-models/home.page.ts | 4 -
tests/specs/receive/receive.spec.ts | 20 +++++
6 files changed, 148 insertions(+), 22 deletions(-)
create mode 100644 src/app/common/utils/sort-assets-by-symbol.ts
create mode 100644 tests/specs/receive/receive.spec.ts
diff --git a/src/app/common/utils/sort-assets-by-symbol.ts b/src/app/common/utils/sort-assets-by-symbol.ts
new file mode 100644
index 00000000000..20e1baa3fa4
--- /dev/null
+++ b/src/app/common/utils/sort-assets-by-symbol.ts
@@ -0,0 +1,23 @@
+interface Asset {
+ name: string;
+ icon: string;
+}
+
+export function sortAssetsBySymbol(assets: Asset[]) {
+ return assets
+ .sort((a, b) => {
+ if (a.name < b.name) return -1;
+ if (a.name > b.name) return 1;
+ return 0;
+ })
+ .sort((a, b) => {
+ if (a.name === 'STX') return -1;
+ if (b.name !== 'STX') return 1;
+ return 0;
+ })
+ .sort((a, b) => {
+ if (a.name === 'BTC') return -1;
+ if (b.name !== 'BTC') return 1;
+ return 0;
+ });
+}
diff --git a/src/app/pages/receive/components/receive-collectibles.tsx b/src/app/pages/receive/components/receive-collectibles.tsx
index 49043c369fc..f21c7c7a438 100644
--- a/src/app/pages/receive/components/receive-collectibles.tsx
+++ b/src/app/pages/receive/components/receive-collectibles.tsx
@@ -12,16 +12,16 @@ import { receiveTabStyle } from '../receive-dialog';
import { ReceiveItem } from './receive-item';
interface ReceiveCollectiblesProps {
- btcAddressTaproot: string;
btcAddressNativeSegwit: string;
+ btcAddressTaproot: string;
stxAddress: string;
onClickQrOrdinal(): void;
onClickQrStacksNft(): void;
onClickQrStamp(): void;
}
export function ReceiveCollectibles({
- btcAddressTaproot,
btcAddressNativeSegwit,
+ btcAddressTaproot,
stxAddress,
onClickQrOrdinal,
onClickQrStacksNft,
diff --git a/src/app/pages/receive/components/receive-tokens.tsx b/src/app/pages/receive/components/receive-tokens.tsx
index e1dfe81c93c..e2e89d4e9e3 100644
--- a/src/app/pages/receive/components/receive-tokens.tsx
+++ b/src/app/pages/receive/components/receive-tokens.tsx
@@ -1,10 +1,22 @@
+import { useMemo } from 'react';
+
import { HomePageSelectors } from '@tests/selectors/home.selectors';
import { css } from 'leather-styles/css';
import { Stack } from 'leather-styles/jsx';
+import { isDefined } from '@shared/utils';
+
import { copyToClipboard } from '@app/common/utils/copy-to-clipboard';
+import { sortAssetsBySymbol } from '@app/common/utils/sort-assets-by-symbol';
import { useToast } from '@app/features/toasts/use-toast';
+import { useAlexSdkSwappableCurrencyQuery } from '@app/query/common/alex-sdk/swappable-currency.query';
+import { useConfigRunesEnabled } from '@app/query/common/remote-config/remote-config.query';
+import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
+import { Avatar, defaultFallbackDelay, getAvatarFallback } from '@app/ui/components/avatar/avatar';
+import { Brc20AvatarIcon } from '@app/ui/components/avatar/brc20-avatar-icon';
import { BtcAvatarIcon } from '@app/ui/components/avatar/btc-avatar-icon';
+import { RunesAvatarIcon } from '@app/ui/components/avatar/runes-avatar-icon';
+import { Src20AvatarIcon } from '@app/ui/components/avatar/src20-avatar-icon';
import { StxAvatarIcon } from '@app/ui/components/avatar/stx-avatar-icon';
import { receiveTabStyle } from '../receive-dialog';
@@ -12,17 +24,35 @@ import { ReceiveItem } from './receive-item';
interface ReceiveTokensProps {
btcAddressNativeSegwit: string;
+ btcAddressTaproot: string;
stxAddress: string;
onClickQrBtc(): void;
onClickQrStx(): void;
}
export function ReceiveTokens({
btcAddressNativeSegwit,
+ btcAddressTaproot,
stxAddress,
onClickQrBtc,
onClickQrStx,
}: ReceiveTokensProps) {
const toast = useToast();
+ const network = useCurrentNetwork();
+ const runesEnabled = useConfigRunesEnabled();
+ const { data: supportedCurrencies = [] } = useAlexSdkSwappableCurrencyQuery();
+
+ const receivableAssets = useMemo(
+ () =>
+ sortAssetsBySymbol(supportedCurrencies.filter(isDefined))
+ .filter(asset => asset.name !== 'STX')
+ .map(asset => ({
+ address: stxAddress,
+ fallback: getAvatarFallback(asset.name),
+ icon: asset.icon,
+ name: asset.name,
+ })),
+ [stxAddress, supportedCurrencies]
+ );
return (
+ }
+ dataTestId={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn}
+ onCopyAddress={async () => {
+ await copyToClipboard(btcAddressTaproot);
+ toast.success('Copied to clipboard!');
+ }}
+ // onClickQrCode={onClickQrOrdinal}
+ title="BRC-20"
/>
+ }
+ // onClickQrCode={onClickQrStamp}
+ onCopyAddress={async () => {
+ await copyToClipboard(btcAddressNativeSegwit);
+ toast.success('Copied to clipboard!');
+ }}
+ title="SRC-20"
+ />
+ {(network.chain.bitcoin.bitcoinNetwork === 'testnet' || runesEnabled) && (
+ }
+ // onClickQrCode={onClickQrStamp}
+ onCopyAddress={async () => {
+ await copyToClipboard(btcAddressNativeSegwit);
+ toast.success('Copied to clipboard!');
+ }}
+ title="Runes"
+ />
+ )}
+
+ {receivableAssets.map(asset => (
+
+
+ {asset.fallback}
+
+ }
+ // onClickQrCode={() => null}
+ onCopyAddress={async () => {
+ await copyToClipboard(asset.address);
+ toast.success('Copied to clipboard!');
+ }}
+ title={asset.name}
+ />
+ ))}
);
}
diff --git a/src/app/pages/receive/receive-dialog.tsx b/src/app/pages/receive/receive-dialog.tsx
index 1060e68bac8..c3d189dce5a 100644
--- a/src/app/pages/receive/receive-dialog.tsx
+++ b/src/app/pages/receive/receive-dialog.tsx
@@ -1,6 +1,7 @@
import { useLocation, useNavigate } from 'react-router-dom';
import { HomePageSelectors } from '@tests/selectors/home.selectors';
+import { Box } from 'leather-styles/jsx';
import get from 'lodash.get';
import { RouteUrls } from '@shared/route-urls';
@@ -109,20 +110,24 @@ export function ReceiveDialog({ type = 'full' }: ReceiveDialogProps) {
-
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtc}`, {
- state: { backgroundLocation },
- })
- }
- onClickQrStx={() =>
- navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
- state: { backgroundLocation, btcAddressTaproot },
- })
- }
- />
+ {/* FIXME 96px should be sizes.footerHeight */}
+
+
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveBtc}`, {
+ state: { backgroundLocation },
+ })
+ }
+ onClickQrStx={() =>
+ navigate(`${RouteUrls.Home}${RouteUrls.ReceiveStx}`, {
+ state: { backgroundLocation, btcAddressTaproot },
+ })
+ }
+ />
+
diff --git a/tests/page-object-models/home.page.ts b/tests/page-object-models/home.page.ts
index 477bee70a79..8854dac5bc7 100644
--- a/tests/page-object-models/home.page.ts
+++ b/tests/page-object-models/home.page.ts
@@ -56,10 +56,6 @@ export class HomePage {
await this.page.getByTestId(HomePageSelectors.ReceiveCryptoAssetBtn).click();
}
- async goToSwapPage() {
- await this.page.getByTestId(HomePageSelectors.SwapBtn).click();
- }
-
// Open issue with Playwright's ability to copyToClipboard from legacy tests:
// https://github.com/microsoft/playwright/issues/8114#issuecomment-1103317576
// Also, an open issue to consistently determine `isMac` in the workaround:
diff --git a/tests/specs/receive/receive.spec.ts b/tests/specs/receive/receive.spec.ts
new file mode 100644
index 00000000000..1c318d96218
--- /dev/null
+++ b/tests/specs/receive/receive.spec.ts
@@ -0,0 +1,20 @@
+import { test } from '../../fixtures/fixtures';
+
+test.describe('Receive Dialog', () => {
+ test.beforeAll(async ({ extensionId, globalPage, onboardingPage, homePage }) => {
+ await globalPage.setupAndUseApiCalls(extensionId);
+ await onboardingPage.signInExistingUser();
+ await homePage.goToReceiveDialog();
+ });
+
+ test('That the Receive dialog renders and shows the correct assets', async ({ homePage }) => {
+ test.expect(homePage.page.getByText('CHOOSE ASSET TO RECEIVE')).toBeTruthy();
+ test.expect(homePage.page.getByText('Tokens')).toBeTruthy();
+ test.expect(homePage.page.getByText('Collectibles')).toBeTruthy();
+
+ test.expect(homePage.page.getByText('Bitcoin')).toBeTruthy();
+ test.expect(homePage.page.getByText('Stacks')).toBeTruthy();
+ test.expect(homePage.page.getByText('BRC-20')).toBeTruthy();
+ test.expect(homePage.page.getByText('SRC-20')).toBeTruthy();
+ });
+});