Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
c56df3d
feat: add swaps english translations
mchappell Nov 5, 2025
29dc093
feat: add swaps svg icons
mchappell Nov 5, 2025
3b10433
feat: add auto-set collateral if available
mchappell Nov 5, 2025
405b86d
feat: add posthog feature flags for swaps
mchappell Nov 5, 2025
3496716
feat: add swaps menu items and routing
mchappell Nov 5, 2025
1e7eb5d
feat(core): update token item to take additional props
mchappell Nov 5, 2025
afd55f2
feat: add webpack + manifest configuration for swaps
mchappell Nov 5, 2025
d738144
feat: add swaps disclaimer
mchappell Nov 5, 2025
8847eee
feat: add swap provider
mchappell Nov 5, 2025
b97340f
feat: add swap provider types
mchappell Nov 5, 2025
4c5deca
feat: add swap utility functions
mchappell Nov 5, 2025
b73c081
feat: add swap stages drawers
mchappell Nov 5, 2025
dc695c5
feat: add main swaps container
mchappell Nov 5, 2025
ea1ad5c
feat: add spanish translations for swaps
mchappell Nov 5, 2025
abf702e
fix: linting
mchappell Nov 5, 2025
15e541b
fix(extension): sync slippage state when drawer opens
rhyslbw Nov 6, 2025
6a62c86
fix(extension): sync liquidity sources state when drawer opens
rhyslbw Nov 6, 2025
561c339
fix(extension): improve slippage input validation
rhyslbw Nov 6, 2025
30cdb1c
fix(extension): validate slippage before saving
rhyslbw Nov 6, 2025
e2d1606
fix(extension): reset error state when slippage drawer opens
rhyslbw Nov 6, 2025
72845aa
docs(extension): add comment explaining feeAdust typo
rhyslbw Nov 6, 2025
826b2dd
fix(extension): prevent slippage reset on targetSlippage changes
rhyslbw Nov 6, 2025
92a5095
fix(extension): capitalize confirm button label in slippage drawer
rhyslbw Nov 6, 2025
86d8342
fix(extension): use translation for confirm button in slippage drawer
rhyslbw Nov 6, 2025
25229bf
fix(extension): standardize SteelSwap capitalization
rhyslbw Nov 6, 2025
a4d6e74
fix(extension): persist slippage setting and prevent feature flag ove…
rhyslbw Nov 6, 2025
1bf9e55
fix(extension): fix stale closure in slippage drawer useEffect
rhyslbw Nov 6, 2025
622ac8e
fix(extension): fix stale closure in liquidity sources drawer
rhyslbw Nov 6, 2025
69d8b53
fix(extension): add type validation for persisted slippage value
rhyslbw Nov 6, 2025
6bba761
fix(extension): correct SwapStage.Failure enum value
rhyslbw Nov 6, 2025
3082aad
fix(extension): add null check in signAndSubmitSwapRequest
rhyslbw Nov 6, 2025
e037930
fix(extension): correct error message in useSwaps hook
rhyslbw Nov 6, 2025
f84731d
fix(extension): add null check in SwapReviewDrawer
rhyslbw Nov 6, 2025
e0f3f8d
fix(extension): prevent race condition in slippage initialization
rhyslbw Nov 6, 2025
aa45f70
fix(extension): fix array mutation in TokenSelectDrawer
rhyslbw Nov 6, 2025
3bac8b0
fix(extension): add null checks for asset balance access
rhyslbw Nov 6, 2025
3a8de38
fix(extension): improve useEffect dependencies and interval cleanup
rhyslbw Nov 6, 2025
7988d15
fix(extension): filter undefined values in getSwapQuoteSources
rhyslbw Nov 6, 2025
846e4bc
fix(extension): correct comment for ESTIMATE_VALIDITY_INTERVAL
rhyslbw Nov 6, 2025
1b2504e
fix(extension): add useRef import in SlippageDrawer
rhyslbw Nov 6, 2025
6e7b648
fix(extension): add validation for quantity number conversion
rhyslbw Nov 6, 2025
6b2739c
fix(extension): fix conditional rendering logic in TokenSelectDrawer
rhyslbw Nov 6, 2025
7e3e230
fix(extension): improve DisclaimerModal storage logic clarity
rhyslbw Nov 6, 2025
bdf5858
fix(extension): improve error handling in fetch functions
rhyslbw Nov 6, 2025
e3e9504
fix(extension): replace console.error with logger for error reporting
rhyslbw Nov 6, 2025
c1e3798
fix(extension): improve error handling consistency in buildSwap
rhyslbw Nov 6, 2025
19e3848
fix(extension): add validation for token decimals to prevent division…
rhyslbw Nov 6, 2025
774d6a0
refactor(extension): extract magic numbers to constants
rhyslbw Nov 6, 2025
a5ab886
fix(extension): add basic validation for API responses
rhyslbw Nov 6, 2025
2ffea2a
fix(extension): restore original error handling in fetchSwappableToke…
rhyslbw Nov 6, 2025
218c66c
refactor(extension): remove auth token requirement from SteelSwap API…
rhyslbw Nov 6, 2025
f044c0d
chore(extension): update default SteelSwap API URL to IOG proxy
rhyslbw Nov 6, 2025
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
6 changes: 6 additions & 0 deletions apps/browser-extension-wallet/.env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,9 @@ HANDLE_RESOLUTION_CACHE_LIFETIME=600000

# mempool.space api
MEMPOOLSPACE_URL=https://mempool.lw.iog.io

# Swaps api
STEELSWAP_API_URL=https://steelswap.lw.iog.io

# NFTcdn.io
ASSET_CDN_URL=http://dev-nft.lw.iog.io
6 changes: 6 additions & 0 deletions apps/browser-extension-wallet/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,9 @@ MEMPOOLSPACE_URL=https://mempool.lw.iog.io

# Local feature flags override
FF_OVERRIDE='{"notifications-center": false}'

# Swaps api
SWAPS_API_URL=

# NFTcdn.io
ASSET_CDN_URL=http://dev-nft.lw.iog.io
2 changes: 1 addition & 1 deletion apps/browser-extension-wallet/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"permissions": ["webRequest", "storage", "tabs", "unlimitedStorage"],
"host_permissions": ["<all_urls>"],
"content_security_policy": {
"extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval'; font-src 'self' data: https://use.typekit.net; object-src 'self'; connect-src $MEMPOOLSPACE_URL $BLOCKFROST_URLS $MAESTRO_URLS $CARDANO_SERVICES_URLS $CARDANO_WS_SERVER_URLS $SENTRY_URL $DAPP_RADAR_APPI_URL https://coingecko.live-mainnet.eks.lw.iog.io https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net https://api.handle.me/ https://*.api.handle.me/ data:; style-src * 'unsafe-inline'; img-src * data: blob:;"
"extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval'; font-src 'self' data: https://use.typekit.net; object-src 'self'; connect-src $MEMPOOLSPACE_URL $BLOCKFROST_URLS $MAESTRO_URLS $CARDANO_SERVICES_URLS $CARDANO_WS_SERVER_URLS $SENTRY_URL $DAPP_RADAR_APPI_URL $STEELSWAP_API_URL $ASSET_CDN_URL https://coingecko.live-mainnet.eks.lw.iog.io https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net https://api.handle.me/ https://*.api.handle.me/ data:; style-src * 'unsafe-inline'; img-src * data: blob:;"
},
"content_scripts": [
{
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import React, { useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { walletRoutePaths } from '../../routes';
Expand All @@ -24,6 +25,9 @@ import TransactionsIconHover from '../../assets/icons/hover-transactions-icon.co
import VotingIconDefault from '../../assets/icons/voting-icon.component.svg';
import VotingIconHover from '../../assets/icons/hover-voting-icon.component.svg';

import SwapIconDefault from '../../assets/icons/trending-up.component.svg';
import SwapIconHover from '../../assets/icons/hover-trending-up.component.svg';

import { MenuItemList } from '@src/utils/constants';
import styles from './MainFooter.module.scss';
import { useAnalyticsContext, useBackgroundServiceAPIContext } from '@providers';
Expand All @@ -38,7 +42,7 @@ const { GOV_TOOLS_URLS } = config();

const includesCoin = /coin/i;

// eslint-disable-next-line complexity
// eslint-disable-next-line complexity, sonarjs/cognitive-complexity
export const MainFooter = (): React.ReactElement => {
const location = useLocation<{ pathname: string }>();
const history = useHistory();
Expand All @@ -48,6 +52,7 @@ export const MainFooter = (): React.ReactElement => {
const backgroundServices = useBackgroundServiceAPIContext();

const isDappExplorerEnabled = posthog.isFeatureFlagEnabled(ExperimentName.DAPP_EXPLORER);
const isSwapCenterEnabled = posthog.isFeatureFlagEnabled(ExperimentName.SWAP_CENTER);
const isVotingCenterEnabled = !!GOV_TOOLS_URLS[environmentName];
const currentLocation = location?.pathname;
const isWalletIconActive =
Expand All @@ -68,6 +73,7 @@ export const MainFooter = (): React.ReactElement => {
const StakingIcon = currentHoveredItem === MenuItemList.STAKING ? StakingIconHover : StakingIconDefault;
const DappExplorerIcon = currentHoveredItem === MenuItemList.DAPPS ? DappExplorerIconHover : DappExplorerIconDefault;
const VotingIcon = currentHoveredItem === MenuItemList.VOTING ? VotingIconHover : VotingIconDefault;
const SwapIcon = currentHoveredItem === MenuItemList.VOTING ? SwapIconHover : SwapIconDefault;

const sendAnalytics = (postHogAction?: PostHogAction) => {
if (postHogAction) {
Expand Down Expand Up @@ -97,6 +103,11 @@ export const MainFooter = (): React.ReactElement => {
break;
}

if (path === walletRoutePaths.swaps) {
backgroundServices.handleOpenBrowser({ section: BrowserViewSections.SWAPS });
return;
}

if (path === walletRoutePaths.dapps) {
backgroundServices.handleOpenBrowser({ section: BrowserViewSections.DAPP_EXPLORER });
return;
Expand Down Expand Up @@ -178,6 +189,20 @@ export const MainFooter = (): React.ReactElement => {
<DappExplorerIcon className={styles.icon} />
</button>
)}
{isSwapCenterEnabled && (
<button
onMouseEnter={() => onMouseEnterItem(MenuItemList.SWAPS)}
onMouseLeave={onMouseLeaveItem}
data-testid="main-footer-swaps"
onClick={() => handleNavigation(walletRoutePaths.swaps)}
>
{currentLocation === walletRoutePaths.swaps ? (
<SwapIconHover className={styles.icon} />
) : (
<SwapIcon className={styles.icon} />
)}
</button>
)}
</div>
</div>
);
Expand Down
29 changes: 27 additions & 2 deletions apps/browser-extension-wallet/src/hooks/useCollateral.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
/* eslint-disable unicorn/no-useless-undefined */
import { useCallback, useMemo, useState } from 'react';
import { useCallback, useMemo, useState, useEffect } from 'react';
import { logger, useObservable } from '@lace/common';
import { firstValueFrom } from 'rxjs';
import { map, take, filter } from 'rxjs/operators';
Expand All @@ -20,6 +21,7 @@ export type UseCollateralReturn = {
txFee: Cardano.Lovelace;
hasEnoughAda: boolean;
txBuilder?: TxBuilder;
availableUtxoCollateral?: Cardano.Utxo[];
};

export const useCollateral = (): UseCollateralReturn => {
Expand All @@ -33,6 +35,10 @@ export const useCollateral = (): UseCollateralReturn => {
const walletAddress = addresses?.[0]?.address;
const hasEnoughAda = useHasEnoughCollateral();
const isSyncingForTheFirstTime = useSyncingTheFirstTime(); // here we check wallet is syncing for the first time
const [availableUtxoCollateral, setAvailableUtxoCollateral] = useState<Cardano.Utxo[]>();
const unspendable = useObservable(inMemoryWallet?.balance?.utxo.unspendable$);
const hasCollateral = useMemo(() => unspendable?.coins >= COLLATERAL_AMOUNT_LOVELACES, [unspendable?.coins]);

const output: Cardano.TxOut = useMemo(
() => ({
address: walletAddress && Cardano.PaymentAddress(walletAddress),
Expand All @@ -43,6 +49,24 @@ export const useCollateral = (): UseCollateralReturn => {
[walletAddress]
);

useEffect(() => {
if (hasCollateral) return;
const checkCollateral = async () => {
// if there aren't any utxos, this will never complete
const utxo = await firstValueFrom(
inMemoryWallet.utxo.available$.pipe(
map((utxos) => utxos.find((o) => !o[1].value?.assets && o[1].value.coins >= COLLATERAL_AMOUNT_LOVELACES)),
filter(isNotNil),
take(1)
)
);
if (utxo.length > 0) {
setAvailableUtxoCollateral([utxo]);
}
};
checkCollateral();
}, [hasEnoughAda, hasCollateral, inMemoryWallet.utxo.available$, unspendable]);

const initializeCollateralTx = useCallback(async () => {
// if the wallet has not been synced at least once or has no balance don't initialize Tx
if (!hasEnoughAda || isSyncingForTheFirstTime) return;
Expand Down Expand Up @@ -103,6 +127,7 @@ export const useCollateral = (): UseCollateralReturn => {
isSubmitting,
txFee,
hasEnoughAda,
txBuilder
txBuilder,
availableUtxoCollateral
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ const handleOpenBrowser = async (data: OpenBrowserData) => {
case BrowserViewSections.DAPP_EXPLORER:
path = walletRoutePaths.dapps;
break;
case BrowserViewSections.SWAPS:
path = walletRoutePaths.swaps;
break;
}
const params = data.urlSearchParams ? `?${data.urlSearchParams}` : '';
const url = `app.html#${path}${params}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export enum BrowserViewSections {
ADD_SHARED_WALLET = 'add_shared_wallet',
NAMI_MIGRATION = 'nami_migration',
NAMI_HW_FLOW = 'nami_hw_flow',
DAPP_EXPLORER = 'dapp-explorer'
DAPP_EXPLORER = 'dapp-explorer',
SWAPS = 'swaps'
}

export interface OpenBrowserData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { Cardano } from '@cardano-sdk/core';
import { z } from 'zod';
import { DeepRequired } from 'utility-types';
import { JsonType } from 'posthog-js';
import { commonSchema, dappExplorerSchema, glacierDropSchema } from '@providers/PostHogClientProvider/schema';
import {
commonSchema,
dappExplorerSchema,
glacierDropSchema,
swapCenterSchema
} from '@providers/PostHogClientProvider/schema';

export enum ExperimentName {
CREATE_PAPER_WALLET = 'create-paper-wallet',
Expand All @@ -17,7 +22,8 @@ export enum ExperimentName {
NFTPRINTLAB = 'nftprintlab',
GLACIER_DROP = 'glacier-drop',
MEMPOOLSPACE_FEE_MARKET = 'bitcoin-mempool-space-fee-market',
NOTIFICATIONS_CENTER = 'notifications-center'
NOTIFICATIONS_CENTER = 'notifications-center',
SWAP_CENTER = 'swap-center'
}

export type FeatureFlag = `${ExperimentName}`;
Expand All @@ -33,6 +39,7 @@ export type FeatureFlagsByNetwork = Record<Cardano.NetworkMagics, FeatureFlags>;
export type FeatureFlagCommonSchema = DeepRequired<z.infer<typeof commonSchema>>;
export type FeatureFlagDappExplorerSchema = DeepRequired<z.infer<typeof dappExplorerSchema>>;
export type FeatureFlagGlacierDropSchema = DeepRequired<z.infer<typeof glacierDropSchema>>;
export type FeatureFlagSwapCenterSchema = DeepRequired<z.infer<typeof swapCenterSchema>>;

// Using `false` as a fallback type for the payload, as it can be optional, and we (sadly) don't have
// strict null checks enabled so `false` is a replacement for `undefined` in this case
Expand All @@ -42,6 +49,7 @@ type FeatureFlagPayload<T extends Record<string, unknown> = {}> = (FeatureFlagCo
type FeatureFlagCustomPayloads = {
[ExperimentName.DAPP_EXPLORER]: FeatureFlagPayload<FeatureFlagDappExplorerSchema>;
[ExperimentName.GLACIER_DROP]: FeatureFlagPayload<FeatureFlagGlacierDropSchema>;
[ExperimentName.SWAP_CENTER]: FeatureFlagPayload<FeatureFlagSwapCenterSchema>;
};

export type FeatureFlagPayloads = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface ExtensionUpdateData {
export const AUTHORIZED_DAPPS_KEY = 'authorizedDapps';
export const ABOUT_EXTENSION_KEY = 'aboutExtension';
export const MIDNIGHT_EVENT_BANNER_KEY = 'midnightEventBanner';
export const SWAPS_DISCLAIMER_ACKNOWLEDGED = 'swapsDisclaimerAcknowledged';
export const SWAPS_TARGET_SLIPPAGE = 'swapsTargetSlippage';

export interface BackgroundStorage {
message?: Message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import {
FeatureFlagsByNetwork,
FeatureFlags,
RawFeatureFlagPayloads,
FeatureFlagGlacierDropSchema
FeatureFlagGlacierDropSchema,
FeatureFlagSwapCenterSchema
} from '@lib/scripts/types/feature-flags';
import { config } from '@src/config';
import { featureFlagSchema, networksEnumSchema, NetworksEnumSchema } from '../schema';
Expand Down Expand Up @@ -338,6 +339,11 @@ export class PostHogClient<Action extends string = string> {
continue;
}

if (featureFlag === ExperimentName.SWAP_CENTER) {
payloadsByFeature[featureFlag] = featureFlagSchema.swapCenter.parse(payload) as FeatureFlagSwapCenterSchema;
continue;
}

// type-casting can be removed after Lace uses strict null checks
payloadsByFeature[featureFlag] = featureFlagSchema.common.parse(payload) as FeatureFlagCommonSchema;
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const defaultFeatureFlags: FeatureFlags = {
[ExperimentName.NFTPRINTLAB]: false,
[ExperimentName.GLACIER_DROP]: false,
[ExperimentName.MEMPOOLSPACE_FEE_MARKET]: false,
[ExperimentName.NOTIFICATIONS_CENTER]: false
[ExperimentName.NOTIFICATIONS_CENTER]: false,
[ExperimentName.SWAP_CENTER]: false
};

export const featureFlagsByNetworkInitialValue: FeatureFlagsByNetwork = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,17 @@ export const glacierDropSchema = commonSchema.merge(
})
);

export const swapCenterSchema = commonSchema.merge(
z.object({
defaultSlippagePercentages: z.array(z.number()),
initialSlippagePercentage: z.number(),
maxSlippagePercentage: z.number()
})
);

export const featureFlagSchema = {
common: z.preprocess(parseJsonPreprocessor, commonSchema),
dappExplorer: z.preprocess(parseJsonPreprocessor, dappExplorerSchema),
glacierDrop: z.preprocess(parseJsonPreprocessor, glacierDropSchema)
glacierDrop: z.preprocess(parseJsonPreprocessor, glacierDropSchema),
swapCenter: z.preprocess(parseJsonPreprocessor, swapCenterSchema)
};
3 changes: 2 additions & 1 deletion apps/browser-extension-wallet/src/routes/wallet-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export const walletRoutePaths = {
customize: '/nami/migration/customize',
allDone: '/nami/migration/all-done',
hwFlow: '/nami/nami-mode/hwTab'
}
},
swaps: '/swaps'
};

export const dAppRoutePaths = {
Expand Down
3 changes: 2 additions & 1 deletion apps/browser-extension-wallet/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ export enum MenuItemList {
TRANSACTIONS = 'transactions',
STAKING = 'staking',
DAPPS = 'dapps',
VOTING = 'voting'
VOTING = 'voting',
SWAPS = 'swaps'
}

export const POPUP_WINDOW = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const SideMenu = (): React.ReactElement => {
const analytics = useAnalyticsContext();
const posthog = usePostHogClientContext();
const isDappExplorerEnabled = posthog.isFeatureFlagEnabled(ExperimentName.DAPP_EXPLORER);
const isSwapCenterEnabled = posthog.isFeatureFlagEnabled(ExperimentName.SWAP_CENTER);

const { isSharedWallet, environmentName } = useWalletStore();
const { blockchain } = useCurrentBlockchain();

Expand Down Expand Up @@ -66,6 +68,8 @@ export const SideMenu = (): React.ReactElement => {
case routes.nfts:
sendAnalytics(PostHogAction.NFTsClick);
break;
case routes.swaps:
sendAnalytics(PostHogAction.SwapsClick);
}
push(field.key);
};
Expand All @@ -87,6 +91,9 @@ export const SideMenu = (): React.ReactElement => {
if (!isVotingCenterEnabled) {
excludeItems.push(MenuItemList.VOTING);
}
if (!isSwapCenterEnabled) {
excludeItems.push(MenuItemList.SWAPS);
}
const menuItems = sideMenuConfig.filter((item) => !excludeItems.includes(item.id));

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import DappExplorerIconActive from '@assets/icons/tiles-solid-gradient.component
import VotingIconDefault from '@assets/icons/voting-icon.component.svg';
import VotingIconHover from '@assets/icons/hover-voting-icon.component.svg';

import SwapIconDefault from '@assets/icons/trending-up.component.svg';
import SwapIconHover from '@assets/icons/hover-trending-up.component.svg';

import { SideMenuItemConfig } from '@types';

export const sideMenuConfig: SideMenuItemConfig[] = [
Expand Down Expand Up @@ -82,6 +85,15 @@ export const sideMenuConfig: SideMenuItemConfig[] = [
regularIcon: DappExplorerIconDefault,
hoverIcon: DappExplorerIconHover,
activeIcon: DappExplorerIconActive
},
{
id: MenuItemList.SWAPS,
label: 'browserView.sideMenu.links.swapsCenter',
testId: 'item-swaps',
path: routes.swaps,
regularIcon: SwapIconDefault,
hoverIcon: SwapIconHover,
activeIcon: SwapIconHover
}
];

Expand Down
Loading
Loading