diff --git a/src/apps/pillarx-app/api/homeFeed.ts b/src/apps/pillarx-app/api/homeFeed.ts index fe66c374..717e3468 100644 --- a/src/apps/pillarx-app/api/homeFeed.ts +++ b/src/apps/pillarx-app/api/homeFeed.ts @@ -8,28 +8,26 @@ import { addMiddleware } from '../../../store'; import { ApiResponse, WalletData } from '../../../types/api'; // utils -import { CompatibleChains } from '../../../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../../../utils/blockchain'; -const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); +const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); export const homeFeedApi = createApi({ reducerPath: 'homeFeedApi', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://feed-nubpgwxpiq-uc.a.run.app' - : 'https://feed-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://feed-nubpgwxpiq-uc.a.run.app' + : 'https://feed-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getTilesInfo: builder.query( { query: ({ page, address }) => - `?page=${page}&address=${address}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`, + `?page=${page}&address=${address}&${chainIdsQuery}&testnets=${String(isTestnet)}`, } ), }), @@ -38,10 +36,9 @@ export const homeFeedApi = createApi({ // maxRetries: 5 is the default, and can be omitted. Shown for documentation purposes. const staggeredBaseQuery = retry( fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://walletportfolio-nubpgwxpiq-uc.a.run.app' - : 'https://walletportfolio-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://walletportfolio-nubpgwxpiq-uc.a.run.app' + : 'https://walletportfolio-7eu4izffpa-uc.a.run.app', }), { maxRetries: 5, @@ -54,7 +51,7 @@ export const walletPortfolioTileApi = createApi({ endpoints: (builder) => ({ getWalletInfo: builder.query({ query: ({ address }) => - `?address=${address}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`, + `?address=${address}&${chainIdsQuery}&testnets=${String(isTestnet)}`, }), }), }); diff --git a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap index 596b96d8..6db6fbf1 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap +++ b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap @@ -23,69 +23,67 @@ exports[` renders correctly and matches snapshot witho data-testid="random-avatar" fill="none" role="img" - viewBox="0 0 80 80" + viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" > - - - - - - - - - - - - - + + `; diff --git a/src/apps/pillarx-app/components/PillarXLogo/PillarXLogo.tsx b/src/apps/pillarx-app/components/PillarXLogo/PillarXLogo.tsx index eaf51b16..8abaa7eb 100644 --- a/src/apps/pillarx-app/components/PillarXLogo/PillarXLogo.tsx +++ b/src/apps/pillarx-app/components/PillarXLogo/PillarXLogo.tsx @@ -1,10 +1,105 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import { useEffect, useState } from 'react'; + +// images +import CloseIcon from '../../images/add.png'; + +// components +import { isTestnet } from '../../../../utils/blockchain'; +import Body from '../Typography/Body'; +import BodySmall from '../Typography/BodySmall'; + type PillarXLogoProps = { src: string; className?: string; }; export const PillarXLogo = ({ src, className }: PillarXLogoProps) => { - return pillar-x-logo; + const [clickCount, setClickCount] = useState(0); + const [isModalOpen, setIsModalOpen] = useState(false); + const [timer, setTimer] = useState(null); + const [isTestnetSwitch, setIsTestnetSwitch] = useState( + String(isTestnet) + ); + + const handleLogoClick = () => { + if (clickCount === 0) { + const newTimer = setTimeout(() => { + setClickCount(0); + }, 4000); + setTimer(newTimer); + } + + setClickCount((prevCount) => prevCount + 1); + + if (clickCount + 1 === 7) { + setIsModalOpen(true); + setClickCount(0); + if (timer) clearTimeout(timer); + } + }; + + const closeModal = () => { + setIsModalOpen(false); + }; + + useEffect(() => { + localStorage.setItem('isTestnet', isTestnetSwitch); + }, [isTestnetSwitch]); + + const handleToggle = () => { + setIsTestnetSwitch((prevState) => { + const newState = prevState === 'true' ? 'false' : 'true'; + setTimeout(() => { + window.location.reload(); + }, 500); + return newState; + }); + }; + + return ( + <> + pillar-x-logo + {isModalOpen && ( +
+
+ close-modal-button + Switch network +
+ Mainnet +
+ +
+ Testnet +
+
+
+ )} + + ); }; export default PillarXLogo; diff --git a/src/apps/pillarx-app/components/PillarXLogo/test/__snapshots__/PillarXLogo.test.tsx.snap b/src/apps/pillarx-app/components/PillarXLogo/test/__snapshots__/PillarXLogo.test.tsx.snap index 86354477..6f7a3a4a 100644 --- a/src/apps/pillarx-app/components/PillarXLogo/test/__snapshots__/PillarXLogo.test.tsx.snap +++ b/src/apps/pillarx-app/components/PillarXLogo/test/__snapshots__/PillarXLogo.test.tsx.snap @@ -5,11 +5,13 @@ exports[` renders correctly and matches snapshot 1`] = ` pillar-x-logo, pillar-x-logo, ] diff --git a/src/apps/pillarx-app/images/add.png b/src/apps/pillarx-app/images/add.png new file mode 100644 index 00000000..8ab472f2 Binary files /dev/null and b/src/apps/pillarx-app/images/add.png differ diff --git a/src/apps/token-atlas/api/token.ts b/src/apps/token-atlas/api/token.ts index 50fbe6ee..5060979a 100644 --- a/src/apps/token-atlas/api/token.ts +++ b/src/apps/token-atlas/api/token.ts @@ -12,21 +12,19 @@ import { } from '../../../types/api'; // utils -import { CompatibleChains } from '../../../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../../../utils/blockchain'; -const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); +const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); export const tokenInfoApi = createApi({ reducerPath: 'tokenInfoApi', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://token-nubpgwxpiq-uc.a.run.app' - : 'https://token-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://token-nubpgwxpiq-uc.a.run.app' + : 'https://token-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getTokenInfo: builder.query< @@ -36,7 +34,7 @@ export const tokenInfoApi = createApi({ query: ({ asset, blockchain, symbol }) => { const blockchainParam = blockchain !== undefined ? `&blockchain=${blockchain}` : ''; - return `?asset=${asset}&symbol=${symbol}${blockchainParam}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`; + return `?asset=${asset}&symbol=${symbol}${blockchainParam}&${chainIdsQuery}&testnets=${String(isTestnet)}`; }, }), }), @@ -45,10 +43,9 @@ export const tokenInfoApi = createApi({ export const tokenGraphApi = createApi({ reducerPath: 'tokenGraphApi', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://tokenpricehistory-nubpgwxpiq-uc.a.run.app' - : 'https://tokenpricehistory-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://tokenpricehistory-nubpgwxpiq-uc.a.run.app' + : 'https://tokenpricehistory-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getTokenGraph: builder.query< @@ -60,7 +57,7 @@ export const tokenGraphApi = createApi({ const blockchainParam = blockchain !== undefined ? `&blockchain=${blockchain}` : ''; const assetParam = asset.split(' ')[0]; - return `?asset=${assetParam}&from=${from * 1000}${toParam}${blockchainParam}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`; + return `?asset=${assetParam}&from=${from * 1000}${toParam}${blockchainParam}&${chainIdsQuery}&testnets=${String(isTestnet)}`; }, }), }), @@ -69,15 +66,13 @@ export const tokenGraphApi = createApi({ export const trendingTokensApi = createApi({ reducerPath: 'trendingTokensApi', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://trendingtokens-nubpgwxpiq-uc.a.run.app' - : 'https://trendingtokens-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://trendingtokens-nubpgwxpiq-uc.a.run.app' + : 'https://trendingtokens-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getTrendingTokens: builder.query({ - query: () => - `?${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`, + query: () => `?${chainIdsQuery}&testnets=${String(isTestnet)}`, }), }), }); @@ -85,15 +80,13 @@ export const trendingTokensApi = createApi({ export const blockchainsListApi = createApi({ reducerPath: 'blockchainsListApi', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://blockchains-nubpgwxpiq-uc.a.run.app' - : 'https://blockchains-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://blockchains-nubpgwxpiq-uc.a.run.app' + : 'https://blockchains-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getBlockchainsList: builder.query({ - query: () => - `?${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`, + query: () => `?${chainIdsQuery}&testnets=${String(isTestnet)}`, }), }), }); diff --git a/src/containers/Main.tsx b/src/containers/Main.tsx index 9e266c49..d566c094 100644 --- a/src/containers/Main.tsx +++ b/src/containers/Main.tsx @@ -32,7 +32,7 @@ import Lobby from '../pages/Lobby'; import Login from '../pages/Login'; import NotFound from '../pages/NotFound'; import Waitlist from '../pages/WaitList'; -import { visibleChains } from '../utils/blockchain'; +import { isTestnet, visibleChains } from '../utils/blockchain'; import Authorized from './Authorized'; /** @@ -257,8 +257,7 @@ const Main = () => { appId={process.env.REACT_APP_PRIVY_APP_ID as string} config={{ appearance: { theme: 'dark' }, - defaultChain: - process.env.REACT_APP_USE_TESTNETS === 'true' ? sepolia : polygon, + defaultChain: isTestnet ? sepolia : polygon, embeddedWallets: { createOnLogin: 'users-without-wallets', }, diff --git a/src/providers/AllowedAppsProvider.tsx b/src/providers/AllowedAppsProvider.tsx index 705944e8..182c86d8 100644 --- a/src/providers/AllowedAppsProvider.tsx +++ b/src/providers/AllowedAppsProvider.tsx @@ -3,7 +3,7 @@ import axios from 'axios'; import React, { createContext, useEffect, useMemo } from 'react'; // utils -import { CompatibleChains } from '../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../utils/blockchain'; export interface AllowedAppsContextProps { data: { @@ -29,19 +29,18 @@ const AllowedAppsProvider = ({ children }: { children: React.ReactNode }) => { (async () => { try { - const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); + const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); const { data } = await axios.get( - process.env.REACT_APP_USE_TESTNETS === 'true' + isTestnet ? 'https://apps-nubpgwxpiq-uc.a.run.app' : 'https://apps-7eu4izffpa-uc.a.run.app', { params: { - testnets: process.env.REACT_APP_USE_TESTNETS || 'true', + testnets: String(isTestnet), }, paramsSerializer: () => `${chainIdsQuery}`, } diff --git a/src/services/pillarXApiPresence.ts b/src/services/pillarXApiPresence.ts index 3d808203..5e287e0d 100644 --- a/src/services/pillarXApiPresence.ts +++ b/src/services/pillarXApiPresence.ts @@ -2,27 +2,25 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // utils -import { CompatibleChains } from '../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../utils/blockchain'; export const pillarXApiPresence = createApi({ reducerPath: 'pillarXApiPresence', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://activity-nubpgwxpiq-uc.a.run.app' - : 'https://activity-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://activity-nubpgwxpiq-uc.a.run.app' + : 'https://activity-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ recordPresence: builder.mutation({ query: (payload = {}) => { - const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); + const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); return { - url: `?${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`, + url: `?${chainIdsQuery}&testnets=${String(isTestnet)}`, method: 'POST', body: payload, }; diff --git a/src/services/pillarXApiTransactionsHistory.tsx b/src/services/pillarXApiTransactionsHistory.tsx index d6f28ef1..d66200ac 100644 --- a/src/services/pillarXApiTransactionsHistory.tsx +++ b/src/services/pillarXApiTransactionsHistory.tsx @@ -2,27 +2,25 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // utils -import { CompatibleChains } from '../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../utils/blockchain'; // Define a service using a base URL and expected endpoints export const pillarXApiTransactionsHistory = createApi({ reducerPath: 'pillarXApiTransactionsHistory', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://transactions-nubpgwxpiq-uc.a.run.app' - : 'https://transactions-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://transactions-nubpgwxpiq-uc.a.run.app' + : 'https://transactions-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getTransactionsHistory: builder.query({ query: ({ address }) => { - const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); + const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); - return `?address=${address}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`; + return `?address=${address}&${chainIdsQuery}&testnets=${String(isTestnet)}`; }, }), }), diff --git a/src/services/pillarXApiWaitlist.ts b/src/services/pillarXApiWaitlist.ts index e9c9d009..5394834c 100644 --- a/src/services/pillarXApiWaitlist.ts +++ b/src/services/pillarXApiWaitlist.ts @@ -2,26 +2,24 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // utils -import { CompatibleChains } from '../utils/blockchain'; +import { CompatibleChains, isTestnet } from '../utils/blockchain'; // Define a service using a base URL and expected endpoints export const pillarXApiWaitlist = createApi({ reducerPath: 'pillarXApiWaitlistWaitlist', baseQuery: fetchBaseQuery({ - baseUrl: - process.env.REACT_APP_USE_TESTNETS === 'true' - ? 'https://waitlist-nubpgwxpiq-uc.a.run.app' - : 'https://waitlist-7eu4izffpa-uc.a.run.app', + baseUrl: isTestnet + ? 'https://waitlist-nubpgwxpiq-uc.a.run.app' + : 'https://waitlist-7eu4izffpa-uc.a.run.app', }), endpoints: (builder) => ({ getWaitlist: builder.query({ query: ({ address }) => { - const chainIds = - process.env.REACT_APP_USE_TESTNETS === 'true' - ? [11155111] - : CompatibleChains.map((chain) => chain.chainId); + const chainIds = isTestnet + ? [11155111] + : CompatibleChains.map((chain) => chain.chainId); const chainIdsQuery = chainIds.map((id) => `chainIds=${id}`).join('&'); - return `?address=${address}&${chainIdsQuery}&testnets=${process.env.REACT_APP_USE_TESTNETS || 'true'}`; + return `?address=${address}&${chainIdsQuery}&testnets=${String(isTestnet)}`; }, }), }), diff --git a/src/utils/blockchain.ts b/src/utils/blockchain.ts index 3c9bd83a..56bfd60b 100644 --- a/src/utils/blockchain.ts +++ b/src/utils/blockchain.ts @@ -23,6 +23,14 @@ import logoEvm from '../assets/images/logo-evm.png'; import logoGnosis from '../assets/images/logo-gnosis.png'; import logoPolygon from '../assets/images/logo-polygon.png'; +export const isTestnet = (() => { + const storedIsTestnet = localStorage.getItem('isTestnet'); + if (storedIsTestnet === null || storedIsTestnet === undefined) { + return process.env.REACT_APP_USE_TESTNETS === 'true'; + } + return storedIsTestnet === 'true'; +})(); + export const isValidEthereumAddress = ( address: string | undefined ): boolean => { @@ -118,7 +126,7 @@ export const getNativeAssetForChainId = (chainId: number): TokenListToken => { export const supportedChains = [mainnet, polygon, gnosis, base, sepolia]; export const visibleChains = supportedChains.filter((chain) => - process.env.REACT_APP_USE_TESTNETS === 'true' ? chain.testnet : !chain.testnet + isTestnet ? chain.testnet : !chain.testnet ); export const parseNftTitle = (collection: NftCollection, nft: Nft): string => {