Skip to content

Commit d5d7d69

Browse files
committed
feat(suite): move testnets into experimental features
1 parent 5382897 commit d5d7d69

File tree

17 files changed

+112
-35
lines changed

17 files changed

+112
-35
lines changed

packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/AddAccountModal/AddAccountModal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ import { Translation } from 'src/components/suite/Translation';
2121
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
2222
import { useDispatch, useSelector } from 'src/hooks/suite';
2323
import { selectIsPublic } from 'src/reducers/wallet/coinjoinReducer';
24-
import { selectIsDebugModeActive } from 'src/selectors/suite/suiteSelectors';
24+
import {
25+
selectHasExperimentalFeature,
26+
selectIsDebugModeActive,
27+
} from 'src/selectors/suite/suiteSelectors';
2528
import { TrezorDevice } from 'src/types/suite';
2629
import { Account } from 'src/types/wallet';
2730

@@ -61,6 +64,7 @@ export const AddAccountModal = ({
6164
const isDebug = useSelector(selectIsDebugModeActive);
6265
const isCoinjoinPublic = useSelector(selectIsPublic);
6366
const enabledNetworkSymbols = useSelector(selectEnabledNetworks);
67+
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));
6468
const dispatch = useDispatch();
6569

6670
const { showUnsupportedCoins, supportedMainnets, unsupportedMainnets, supportedTestnets } =
@@ -323,7 +327,7 @@ export const AddAccountModal = ({
323327
handleNetworkSelection={selectNetwork}
324328
/>
325329
</NetworksWrapper>
326-
{!symbol && !!disabledTestnetNetworks.length && (
330+
{!symbol && !!disabledTestnetNetworks.length && useTestnetNetworks && (
327331
<CollapsibleBox
328332
heading={
329333
<Tooltip

packages/suite/src/constants/suite/experimental.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const experimentalNetworkNames = experimentalNetworks.map(network => network.nam
1515
export type ExperimentalFeature =
1616
| 'password-manager'
1717
| 'tor-external'
18+
| 'testnet-networks'
1819
| 'nft-section'
1920
| 'experimental-networks';
2021
// | 'suite-sync';
@@ -50,6 +51,10 @@ export const EXPERIMENTAL_FEATURES: Record<ExperimentalFeature, ExperimentalFeat
5051
}
5152
},
5253
},
54+
'testnet-networks': {
55+
title: { id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS' },
56+
description: { id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION' },
57+
},
5358
'nft-section': {
5459
title: { id: 'TR_EXPERIMENTAL_NFT_SECTION' },
5560
description: { id: 'TR_EXPERIMENTAL_NFT_SECTION_DESCRIPTION' },

packages/suite/src/hooks/settings/useNetworkSupport.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export const useNetworkSupport = () => {
1515
const useExperimentalNetworks = useSelector(
1616
selectHasExperimentalFeature('experimental-networks'),
1717
);
18+
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));
1819
const deviceSupportedNetworkSymbols = useSelector(selectDeviceSupportedNetworks);
1920

20-
const mainnets = getMainnets(isDebug, useExperimentalNetworks);
21-
const testnets = getTestnets(isDebug, useExperimentalNetworks);
21+
const mainnets = getMainnets({ debug: isDebug, useExperimentalNetworks });
22+
const testnets = getTestnets({ debug: isDebug, useExperimentalNetworks, useTestnetNetworks });
2223

2324
const isNetworkSupported = (network: Network) =>
2425
deviceSupportedNetworkSymbols.includes(network.symbol);

packages/suite/src/support/messages.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,6 +5336,14 @@ export default defineMessages({
53365336
defaultMessage:
53375337
'Send and receive transactions on the {networkNames} {count, plural, one {network} other {networks}}.',
53385338
},
5339+
TR_EXPERIMENTAL_TESTNET_NETWORKS: {
5340+
id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS',
5341+
defaultMessage: 'Testnet networks',
5342+
},
5343+
TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION: {
5344+
id: 'TR_EXPERIMENTAL_TESTNET_NETWORKS_DESCRIPTION',
5345+
defaultMessage: 'Send and receive transactions on the testnet networks.',
5346+
},
53395347
TR_EXPERIMENTAL_SUITE_SYNC_TITLE: {
53405348
id: 'TR_EXPERIMENTAL_SUITE_SYNC_TITLE',
53415349
defaultMessage: 'Suite Sync',

packages/suite/src/views/onboarding/steps/CoinsStep/CoinsStepBox.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { CoinGroup } from 'src/components/suite';
1212
import { Translation } from 'src/components/suite/Translation';
1313
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
1414
import { useDispatch, useSelector } from 'src/hooks/suite';
15+
import { selectHasExperimentalFeature } from 'src/selectors/suite/suiteSelectors';
1516
import { getIsTorEnabled } from 'src/utils/suite/tor';
1617

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

2729
// BTC should be enabled by default
2830
useEffect(() => {
@@ -33,18 +35,20 @@ export const CoinsStepBox = (props: OnboardingCardProps) => {
3335
<OnboardingCard iconName="coins" {...props}>
3436
<Column gap={32}>
3537
<CoinGroup networks={supportedMainnets} enabledNetworks={enabledNetworks} />
36-
<CollapsibleBox
37-
heading={
38-
<Tooltip
39-
content={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
40-
hasIcon
41-
>
42-
<Translation id="TR_TESTNET_COINS" />
43-
</Tooltip>
44-
}
45-
>
46-
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
47-
</CollapsibleBox>
38+
{useTestnetNetworks && (
39+
<CollapsibleBox
40+
heading={
41+
<Tooltip
42+
content={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
43+
hasIcon
44+
>
45+
<Translation id="TR_TESTNET_COINS" />
46+
</Tooltip>
47+
}
48+
>
49+
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
50+
</CollapsibleBox>
51+
)}
4852
{showUnsupportedCoins && (
4953
<CollapsibleBox
5054
heading={

packages/suite/src/views/settings/SettingsCoins/SettingsCoins.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { ContextMessage } from 'src/components/wallet/WalletLayout/AccountBanner
2222
import { SettingsAnchor } from 'src/constants/suite/anchors';
2323
import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport';
2424
import { useDevice, useDiscovery, useDispatch, useSelector } from 'src/hooks/suite';
25-
import { selectSuiteFlags } from 'src/selectors/suite/suiteSelectors';
25+
import { selectHasExperimentalFeature, selectSuiteFlags } from 'src/selectors/suite/suiteSelectors';
2626
import { isCoinjoinSupportedSymbol } from 'src/utils/wallet/coinjoinUtils';
2727

2828
import { FirmwareTypeSuggestion } from './FirmwareTypeSuggestion';
@@ -85,6 +85,7 @@ export const SettingsCoins = () => {
8585
const isDiscoveryButtonVisible = useSelector(state =>
8686
selectShowRediscoverButton(state, device),
8787
);
88+
const useTestnetNetworks = useSelector(selectHasExperimentalFeature('testnet-networks'));
8889

8990
const supportedEnabledNetworks = enabledNetworks.filter(enabledNetwork =>
9091
deviceSupportedNetworkSymbols.includes(enabledNetwork),
@@ -132,15 +133,17 @@ export const SettingsCoins = () => {
132133
</SettingsSectionItem>
133134
</SettingsSection>
134135

135-
<SettingsSection
136-
tooltipText={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
137-
title={<Translation id="TR_TESTNET_COINS" />}
138-
icon="coin"
139-
>
140-
<SettingsSectionItem anchorId={SettingsAnchor.TestnetCrypto}>
141-
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
142-
</SettingsSectionItem>
143-
</SettingsSection>
136+
{useTestnetNetworks && (
137+
<SettingsSection
138+
tooltipText={<Translation id="TR_TESTNET_COINS_DESCRIPTION" />}
139+
title={<Translation id="TR_TESTNET_COINS" />}
140+
icon="coin"
141+
>
142+
<SettingsSectionItem anchorId={SettingsAnchor.TestnetCrypto}>
143+
<CoinGroup networks={supportedTestnets} enabledNetworks={enabledNetworks} />
144+
</SettingsSectionItem>
145+
</SettingsSection>
146+
)}
144147

145148
{showUnsupportedCoins && (
146149
<SettingsSection

suite-common/wallet-config/src/__tests__/utils.test.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,37 @@ const mockNetworks = [bitcoin, ethereum, testnet, regtest];
77

88
describe(getMainnets.name, () => {
99
it('returns non-testnet, non-debug-only networks when debug is false', () => {
10-
const result = getMainnets(false, false, mockNetworks);
10+
const result = getMainnets({
11+
allNetworks: mockNetworks,
12+
});
1113
expect(result).toEqual([bitcoin, ethereum]);
1214
});
1315
});
1416

1517
describe(getTestnets.name, () => {
1618
it('returns testnet, non-debug-only networks when debug is false', () => {
17-
const result = getTestnets(false, false, mockNetworks);
19+
const result = getTestnets({
20+
useTestnetNetworks: true,
21+
allNetworks: mockNetworks,
22+
});
1823
expect(result).toEqual([testnet]);
1924
});
2025

2126
it('includes all testnets when debug is true', () => {
22-
const result = getTestnets(true, false, mockNetworks);
27+
const result = getTestnets({
28+
debug: true,
29+
useTestnetNetworks: true,
30+
allNetworks: mockNetworks,
31+
});
2332
expect(result).toEqual([testnet, regtest]);
2433
});
34+
35+
it('returns no testnets when testnet networks feature flag is disabled', () => {
36+
const result = getTestnets({
37+
allNetworks: mockNetworks,
38+
});
39+
expect(result).toEqual([]);
40+
});
2541
});
2642

2743
describe(isAccountOfNetwork.name, () => {

suite-common/wallet-config/src/utils.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,46 @@ export const networksCollection: Network[] = Object.values(networks);
1919
*/
2020
export const networkSymbolCollection = networksCollection.map(n => n.symbol);
2121

22-
export const getMainnets = (
22+
interface GetMainnetsProps {
23+
debug?: boolean;
24+
useExperimentalNetworks?: boolean;
25+
allNetworks?: Network[];
26+
}
27+
28+
export const getMainnets = ({
2329
debug = false,
2430
useExperimentalNetworks = false,
2531
allNetworks = networksCollection,
26-
) =>
32+
}: GetMainnetsProps) =>
2733
allNetworks.filter(
2834
n =>
2935
!n.testnet &&
3036
(!n.isDebugOnlyNetwork || debug) &&
3137
(!n.isExperimentalOnlyNetwork || useExperimentalNetworks),
3238
);
3339

34-
export const getTestnets = (
40+
interface GetTestnetsProps {
41+
debug?: boolean;
42+
useExperimentalNetworks?: boolean;
43+
useTestnetNetworks?: boolean;
44+
allNetworks?: Network[];
45+
}
46+
47+
export const getTestnets = ({
3548
debug = false,
3649
useExperimentalNetworks = false,
50+
useTestnetNetworks = false,
3751
allNetworks = networksCollection,
38-
) =>
52+
}: GetTestnetsProps) =>
3953
allNetworks.filter(
4054
n =>
4155
n.testnet === true &&
56+
useTestnetNetworks &&
4257
(!n.isDebugOnlyNetwork || debug) &&
4358
(!n.isExperimentalOnlyNetwork || useExperimentalNetworks),
4459
);
4560

46-
export const getTestnetSymbols = () => getTestnets().map(n => n.symbol);
61+
export const getTestnetSymbols = () => getTestnets({ useTestnetNetworks: true }).map(n => n.symbol);
4762

4863
export const isBlockbookBasedNetwork = (symbol: NetworkSymbol) =>
4964
networks[symbol]?.backendTypes.some(backend => backend === 'blockbook');

suite/e2e/support/pageObjects/settings/settingsPage.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ export class SettingsPage {
248248
await TrezorUserEnvLinkProxy.pressYes();
249249
}
250250

251+
@step()
252+
async toggleTestnetNetworks() {
253+
await this.navigateTo('application');
254+
await this.page.getByTestId('@settings/experimental-features/toggle-switch').click();
255+
await this.page
256+
.getByTestId('@settings/experimental-features/testnet-networks-checkbox')
257+
.click();
258+
}
259+
251260
@step()
252261
async changeNetworks(options: {
253262
enableNetworks: NetworkSymbol[];

suite/e2e/tests/analytics/events.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ test.describe('Analytics Events', { tag: ['@group=suite', '@webOnly'] }, () => {
146146
await settingsPage.changeFiatCurrency('czk');
147147
await settingsPage.changeBTCUnits('Satoshis');
148148
await settingsPage.changeTheme(Theme.Dark);
149+
await settingsPage.toggleTestnetNetworks();
149150
await settingsPage.navigateTo('coins');
150151
await settingsPage.coins.enableNetwork('eth');
151152
await settingsPage.coins.enableNetwork('thod');
@@ -198,7 +199,7 @@ test.describe('Analytics Events', { tag: ['@group=suite', '@webOnly'] }, () => {
198199
rememberedHiddenWallets: '0',
199200
theme: 'dark',
200201
earlyAccessProgram: 'false',
201-
experimentalFeatures: '',
202+
experimentalFeatures: 'testnet-networks',
202203
autodetectLanguage: 'false',
203204
autodetectTheme: 'false',
204205
isAutomaticUpdateEnabled: 'false',

0 commit comments

Comments
 (0)