Skip to content
Open
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
Expand Up @@ -21,7 +21,10 @@ import { Translation } from 'src/components/suite/Translation';
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
import { useDispatch, useSelector } from 'src/hooks/suite';
import { selectIsPublic } from 'src/reducers/wallet/coinjoinReducer';
import { selectIsDebugModeActive } from 'src/selectors/suite/suiteSelectors';
import {
selectHasExperimentalFeature,
selectIsDebugModeActive,
} from 'src/selectors/suite/suiteSelectors';
import { TrezorDevice } from 'src/types/suite';
import { Account } from 'src/types/wallet';

Expand Down Expand Up @@ -61,6 +64,7 @@ export const AddAccountModal = ({
const isDebug = useSelector(selectIsDebugModeActive);
const isCoinjoinPublic = useSelector(selectIsPublic);
const enabledNetworkSymbols = useSelector(selectEnabledNetworks);
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));
const dispatch = useDispatch();

const { showUnsupportedCoins, supportedMainnets, unsupportedMainnets, supportedTestnets } =
Expand Down Expand Up @@ -323,7 +327,7 @@ export const AddAccountModal = ({
handleNetworkSelection={selectNetwork}
/>
</NetworksWrapper>
{!symbol && !!disabledTestnetNetworks.length && (
{!symbol && !!disabledTestnetNetworks.length && useTestnetNetworks && (
<CollapsibleBox
heading={
<Tooltip
Expand Down
5 changes: 5 additions & 0 deletions packages/suite/src/constants/suite/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const experimentalNetworkNames = experimentalNetworks.map(network => network.nam
export type ExperimentalFeature =
| 'password-manager'
| 'tor-external'
| 'testnet-networks'
| 'nft-section'
| 'experimental-networks';
// | 'suite-sync';
Expand Down Expand Up @@ -50,6 +51,10 @@ export const EXPERIMENTAL_FEATURES: Record<ExperimentalFeature, ExperimentalFeat
}
},
},
'testnet-networks': {
title: { id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS' },
description: { id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION' },
},
'nft-section': {
title: { id: 'TR_EXPERIMENTAL_NFT_SECTION' },
description: { id: 'TR_EXPERIMENTAL_NFT_SECTION_DESCRIPTION' },
Expand Down
5 changes: 3 additions & 2 deletions packages/suite/src/hooks/settings/useNetworkSupport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ export const useNetworkSupport = () => {
const useExperimentalNetworks = useSelector(
selectHasExperimentalFeature('experimental-networks'),
);
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));
const deviceSupportedNetworkSymbols = useSelector(selectDeviceSupportedNetworks);

const mainnets = getMainnets(isDebug, useExperimentalNetworks);
const testnets = getTestnets(isDebug, useExperimentalNetworks);
const mainnets = getMainnets({ debug: isDebug, useExperimentalNetworks });
const testnets = getTestnets({ debug: isDebug, useExperimentalNetworks, useTestnetNetworks });

const isNetworkSupported = (network: Network) =>
deviceSupportedNetworkSymbols.includes(network.symbol);
Expand Down
8 changes: 8 additions & 0 deletions packages/suite/src/support/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5336,6 +5336,14 @@ export default defineMessages({
defaultMessage:
'Send and receive transactions on the {networkNames} {count, plural, one {network} other {networks}}.',
},
TR_EXPERIMENTAL_TESTNET_NETWORKS: {
id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS',
defaultMessage: 'Testnet networks',
},
TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION: {
id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION',
defaultMessage: 'Send and receive transactions on the testnet networks.',
},
TR_EXPERIMENTAL_SUITE_SYNC_TITLE: {
id: 'TR_EXPERIMENTAL_SUITE_SYNC_TITLE',
defaultMessage: 'Suite Sync',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CoinGroup } from 'src/components/suite';
import { Translation } from 'src/components/suite/Translation';
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
import { useDispatch, useSelector } from 'src/hooks/suite';
import { selectHasExperimentalFeature } from 'src/selectors/suite/suiteSelectors';
import { getIsTorEnabled } from 'src/utils/suite/tor';

import { TorSection } from './TorSection';
Expand All @@ -23,6 +24,7 @@ export const CoinsStepBox = (props: OnboardingCardProps) => {
const torStatus = useSelector(state => state.suite.torStatus);
const dispatch = useDispatch();
const isTorEnabled = getIsTorEnabled(torStatus);
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));

// BTC should be enabled by default
useEffect(() => {
Expand All @@ -33,18 +35,20 @@ export const CoinsStepBox = (props: OnboardingCardProps) => {
<OnboardingCard iconName="coins" {...props}>
<Column gap={32}>
<CoinGroup networks={supportedMainnets} enabledNetworks={enabledNetworks} />
<CollapsibleBox
heading={
<Tooltip
content={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
hasIcon
>
<Translation id="TR_TESTNET_COINS" />
</Tooltip>
}
>
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
</CollapsibleBox>
{useTestnetNetworks && (
<CollapsibleBox
heading={
<Tooltip
content={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
hasIcon
>
<Translation id="TR_TESTNET_COINS" />
</Tooltip>
}
>
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
</CollapsibleBox>
)}
{showUnsupportedCoins && (
<CollapsibleBox
heading={
Expand Down
23 changes: 13 additions & 10 deletions packages/suite/src/views/settings/SettingsCoins/SettingsCoins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { ContextMessage } from 'src/components/wallet/WalletLayout/AccountBanner
import { SettingsAnchor } from 'src/constants/suite/anchors';
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
import { useDevice, useDiscovery, useDispatch, useSelector } from 'src/hooks/suite';
import { selectSuiteFlags } from 'src/selectors/suite/suiteSelectors';
import { selectHasExperimentalFeature, selectSuiteFlags } from 'src/selectors/suite/suiteSelectors';
import { isCoinjoinSupportedSymbol } from 'src/utils/wallet/coinjoinUtils';

import { FirmwareTypeSuggestion } from './FirmwareTypeSuggestion';
Expand Down Expand Up @@ -85,6 +85,7 @@ export const SettingsCoins = () => {
const isDiscoveryButtonVisible = useSelector(state =>
selectShowRediscoverButton(state, device),
);
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));

const supportedEnabledNetworks = enabledNetworks.filter(enabledNetwork =>
deviceSupportedNetworkSymbols.includes(enabledNetwork),
Expand Down Expand Up @@ -132,15 +133,17 @@ export const SettingsCoins = () => {
</SettingsSectionItem>
</SettingsSection>

<SettingsSection
tooltipText={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
title={<Translation id="TR_TESTNET_COINS" />}
icon="coin"
>
<SettingsSectionItem anchorId={SettingsAnchor.TestnetCrypto}>
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
</SettingsSectionItem>
</SettingsSection>
{useTestnetNetworks && (
<SettingsSection
tooltipText={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
title={<Translation id="TR_TESTNET_COINS" />}
icon="coin"
>
<SettingsSectionItem anchorId={SettingsAnchor.TestnetCrypto}>
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
</SettingsSectionItem>
</SettingsSection>
)}

{showUnsupportedCoins && (
<SettingsSection
Expand Down
22 changes: 19 additions & 3 deletions suite-common/wallet-config/src/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,37 @@ const mockNetworks = [bitcoin, ethereum, testnet, regtest];

describe(getMainnets.name, () => {
it('returns non-testnet, non-debug-only networks when debug is false', () => {
const result = getMainnets(false, false, mockNetworks);
const result = getMainnets({
allNetworks: mockNetworks,
});
expect(result).toEqual([bitcoin, ethereum]);
});
});

describe(getTestnets.name, () => {
it('returns testnet, non-debug-only networks when debug is false', () => {
const result = getTestnets(false, false, mockNetworks);
const result = getTestnets({
useTestnetNetworks: true,
allNetworks: mockNetworks,
});
expect(result).toEqual([testnet]);
});

it('includes all testnets when debug is true', () => {
const result = getTestnets(true, false, mockNetworks);
const result = getTestnets({
debug: true,
useTestnetNetworks: true,
allNetworks: mockNetworks,
});
expect(result).toEqual([testnet, regtest]);
});

it('returns no testnets when testnet networks feature flag is disabled', () => {
const result = getTestnets({
allNetworks: mockNetworks,
});
expect(result).toEqual([]);
});
});

describe(isAccountOfNetwork.name, () => {
Expand Down
25 changes: 20 additions & 5 deletions suite-common/wallet-config/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,46 @@ export const networksCollection: Network[] = Object.values(networks);
*/
export const networkSymbolCollection = networksCollection.map(n => n.symbol);

export const getMainnets = (
interface GetMainnetsProps {
debug?: boolean;
useExperimentalNetworks?: boolean;
allNetworks?: Network[];
}

export const getMainnets = ({
debug = false,
useExperimentalNetworks = false,
allNetworks = networksCollection,
) =>
}: GetMainnetsProps) =>
allNetworks.filter(
n =>
!n.testnet &&
(!n.isDebugOnlyNetwork || debug) &&
(!n.isExperimentalOnlyNetwork || useExperimentalNetworks),
);

export const getTestnets = (
interface GetTestnetsProps {
debug?: boolean;
useExperimentalNetworks?: boolean;
useTestnetNetworks?: boolean;
allNetworks?: Network[];
}

export const getTestnets = ({
debug = false,
useExperimentalNetworks = false,
useTestnetNetworks = false,
allNetworks = networksCollection,
) =>
}: GetTestnetsProps) =>
allNetworks.filter(
n =>
n.testnet === true &&
useTestnetNetworks &&
(!n.isDebugOnlyNetwork || debug) &&
(!n.isExperimentalOnlyNetwork || useExperimentalNetworks),
);

export const getTestnetSymbols = () => getTestnets().map(n => n.symbol);
export const getTestnetSymbols = () => getTestnets({ useTestnetNetworks: true }).map(n => n.symbol);

export const isBlockbookBasedNetwork = (symbol: NetworkSymbol) =>
networks[symbol]?.backendTypes.some(backend => backend === 'blockbook');
Expand Down
9 changes: 9 additions & 0 deletions suite/e2e/support/pageObjects/settings/settingsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ export class SettingsPage {
await TrezorUserEnvLinkProxy.pressYes();
}

@step()
async toggleTestnetNetworks() {
await this.navigateTo('application');
await this.page.getByTestId('@settings/experimental-features/toggle-switch').click();
await this.page
.getByTestId('@settings/experimental-features/testnet-networks-checkbox')
.click();
}

@step()
async changeNetworks(options: {
enableNetworks: NetworkSymbol[];
Expand Down
3 changes: 2 additions & 1 deletion suite/e2e/tests/analytics/events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ test.describe('Analytics Events', { tag: ['@group=suite', '@webOnly'] }, () => {
await settingsPage.changeFiatCurrency('czk');
await settingsPage.changeBTCUnits('Satoshis');
await settingsPage.changeTheme(Theme.Dark);
await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');
await settingsPage.coins.enableNetwork('eth');
await settingsPage.coins.enableNetwork('thod');
Expand Down Expand Up @@ -198,7 +199,7 @@ test.describe('Analytics Events', { tag: ['@group=suite', '@webOnly'] }, () => {
rememberedHiddenWallets: '0',
theme: 'dark',
earlyAccessProgram: 'false',
experimentalFeatures: '',
experimentalFeatures: 'testnet-networks',
autodetectLanguage: 'false',
autodetectTheme: 'false',
isAutomaticUpdateEnabled: 'false',
Expand Down
4 changes: 4 additions & 0 deletions suite/e2e/tests/settings/coins.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ test.describe('Coin Settings', { tag: ['@group=settings'] }, () => {
];

await test.step('No assets are active', async () => {
await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');

await expect(settingsPage.coins.networkButton('btc')).toBeEnabledCoin();
for (const network of defaultUnchecked) {
await expect(settingsPage.coins.networkButton(network)).toBeDisabledCoin();
Expand All @@ -62,6 +65,7 @@ test.describe('Coin Settings', { tag: ['@group=settings'] }, () => {

await test.step('Activate assets', async () => {
await dashboardPage.discoveryEmptyPrimaryButton.click();
await settingsPage.navigateTo('coins');
for (const network of ['btc', ...defaultUnchecked] as NetworkSymbol[]) {
await settingsPage.coins.enableNetwork(network);
}
Expand Down
1 change: 1 addition & 0 deletions suite/e2e/tests/settings/electrum.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ test.describe(
});
const electrumUrl = '127.0.0.1:50001:t';

await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');
await settingsPage.coins.openNetworkAdvanceSettings('regtest');
await settingsPage.coins.changeBackend('electrum', electrumUrl);
Expand Down
1 change: 1 addition & 0 deletions suite/e2e/tests/settings/without-device.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ test.describe(
await settingsPage.navigateTo('application');
await settingsPage.toggleDebugModeInSettings();

await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');
await settingsPage.coins.enableNetwork('regtest');

Expand Down
2 changes: 2 additions & 0 deletions suite/e2e/tests/wallet/cardano.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ test.describe('Cardano', { tag: ['@group=wallet', '@snapshot'] }, () => {
walletPage,
trezorUserEnvLink,
}) => {
await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');
await settingsPage.coins.enableNetwork('tada');
// await settingsPage.coins.openNetworkAdvanceSettings('tada');
// await expect(settingsPage.modal).toHaveScreenshot('cardano-advanced-settings.png', {
Expand Down
1 change: 1 addition & 0 deletions suite/e2e/tests/wallet/coin-balance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ test.describe('Coin balance', { tag: ['@group=wallet'] }, () => {
const firstAccountBalanceLocator = walletPage.balanceOfAccount('regtest').first();
await trezorUserEnvLink.sendToAddressAndMineBlock({ address, btc_amount: 1 });
await test.step('Regtest discovered with non zero value', async () => {
await settingsPage.toggleTestnetNetworks();
await settingsPage.changeNetworks({ enableNetworks: ['regtest'] });
await dashboardPage.navigateTo();
await expect(walletPage.accountLabel({ symbol: 'regtest' })).toHaveText(
Expand Down
1 change: 1 addition & 0 deletions suite/e2e/tests/wallet/pending-transactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ test.describe(
});

await onboardingPage.completeOnboarding({ keepDebugModeEnabled: true });
await settingsPage.toggleTestnetNetworks();
await settingsPage.changeNetworks({
enableNetworks: ['regtest'],
disableNetworks: ['btc'],
Expand Down
1 change: 1 addition & 0 deletions suite/e2e/tests/wallet/send-form-regtest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ test.describe('Send form for bitcoin', { tag: ['@group=wallet'] }, () => {
async ({ onboardingPage, dashboardPage, settingsPage, walletPage, trezorUserEnvLink }) => {
await onboardingPage.completeOnboarding({ keepDebugModeEnabled: true });

await settingsPage.toggleTestnetNetworks();
await settingsPage.navigateTo('coins');
await settingsPage.coins.enableNetwork('regtest');

Expand Down
Loading