Skip to content

Commit

Permalink
Merge branch 'develop' into mount/unmount-panels
Browse files Browse the repository at this point in the history
  • Loading branch information
walmat authored Jun 11, 2024
2 parents a5a65a1 + 7cdcc7a commit ac83432
Show file tree
Hide file tree
Showing 62 changed files with 552 additions and 588 deletions.
7 changes: 3 additions & 4 deletions e2e/4_discoverSheetFlow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ describe('Discover Screen Flow', () => {
});

it('Should navigate to the Points screen after swiping left', async () => {
await swipe('profile-screen', 'left', 'slow');
await swipe('profile-screen', 'left', 'fast');
await checkIfVisible('points-screen');
});

it('Should navigate back to Discover screen after swiping right twice', async () => {
await swipe('points-screen', 'right', 'slow');
await swipe('profile-screen', 'right', 'slow');
it('Should navigate back to Discover screen after tapping Discover icon', async () => {
await waitAndTap('tab-bar-icon-DiscoverScreen');
await checkIfVisible('discover-header');
});

Expand Down
56 changes: 56 additions & 0 deletions e2e/7_maliciousDappConnection.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
beforeAllcleanApp,
afterAllcleanApp,
importWalletFlow,
waitAndTap,
swipe,
checkIfVisible,
checkIfExistsByText,
typeText,
delayTime,
tapAtPoint,
checkIfExists,
} from './helpers';
import { WALLET_VARS } from './testVariables';

describe('Check malicious dapp warning', () => {
beforeAll(async () => {
await beforeAllcleanApp({ hardhat: false });
});

afterAll(async () => {
await afterAllcleanApp({ hardhat: false });
});

it('Should be able to watch a wallet and load the wallet screen', async () => {
await importWalletFlow(WALLET_VARS.SEED_WALLET.PK);
});

it('Should be able to navigate to the dapp browser', async () => {
await swipe('wallet-screen', 'left', 'fast');
await swipe('discover-sheet', 'left', 'fast');
await checkIfVisible('browser-screen');
});

it('Should be able to type on search input and go to malicious dapp', async () => {
await waitAndTap('browser-search-input');
await checkIfExistsByText('Find apps and more');
await typeText('browser-search-input', 'https://test-dap-welps.vercel.app/', true, false, true);
// Waiting for webpage to load
await delayTime('long');
});

it('Should attempt to connect to in browser dapp', async () => {
// Detox can't query elements within a WebView within our app
// Using tapAtPoint() to tap coordinates is a workaround for now

// Tapping connect button
await tapAtPoint('browser-screen', { x: 275, y: 80 });
// Waiting for rainbowkit sheet to load / animate in
await delayTime('medium');
// Tapping Rainbow button
await tapAtPoint('browser-screen', { x: 50, y: 325 });

await checkIfExists('malicious-dapp-warning');
});
});
2 changes: 1 addition & 1 deletion e2e/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config, context) {
super(config, context);
this.launchAppTimeout = 120_000;
this.initTimeout = 360_000;
this.initTimeout = 120_000;
}
}
module.exports = CustomDetoxEnvironment;
17 changes: 11 additions & 6 deletions e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ export async function killHardhat() {
exec('kill $(lsof -t -i:8545)');
}

export async function importWalletFlow() {
export async function importWalletFlow(customSeed?: string) {
await checkIfVisible('welcome-screen');
await waitAndTap('already-have-wallet-button');
await checkIfExists('add-wallet-sheet');
await waitAndTap('restore-with-key-button');
await checkIfExists('import-sheet');
await clearField('import-sheet-input');
await device.disableSynchronization();
await typeText('import-sheet-input', process.env.TEST_SEEDS, false);
await typeText('import-sheet-input', customSeed ? customSeed : process.env.TEST_SEEDS, false);
await checkIfElementHasString('import-sheet-button-label', 'Continue');
await waitAndTap('import-sheet-button');
await checkIfVisible('wallet-info-modal');
Expand All @@ -52,9 +52,6 @@ export async function importWalletFlow() {
}

export async function beforeAllcleanApp({ hardhat }: { hardhat?: boolean }) {
// sometimes i see tests failed from the get-go
// giving an extra 15 to let things set up
await delayTime('very-long');
jest.resetAllMocks();
hardhat && (await startHardhat());
}
Expand Down Expand Up @@ -127,7 +124,13 @@ export async function startIosSimulator() {
}
}

export async function typeText(elementId: string | RegExp, text: string | undefined, focus = true, syncOnAndroid = false) {
export async function typeText(
elementId: string | RegExp,
text: string | undefined,
focus = true,
syncOnAndroid = false,
hitEnterAfterText = false
) {
if (text === undefined) {
throw new Error(`Cannot type 'undefined' into element with id ${elementId}`);
}
Expand All @@ -140,13 +143,15 @@ export async function typeText(elementId: string | RegExp, text: string | undefi
await device.disableSynchronization();
}
await element(by.id(elementId)).typeText(text);
hitEnterAfterText && (await typeText(elementId, '\n'));
if (device.getPlatform() === 'android' && !syncOnAndroid) {
await device.enableSynchronization();
}
} catch (error) {
throw new Error(`Error typing "${text}" at element with id ${elementId}}: ${error}`);
}
}

export async function typeNumbers(elementId: string | RegExp, text: string, submitLabel: string | RegExp) {
try {
await element(by.id(elementId)).replaceText(text.replace('\n', ''));
Expand Down
2 changes: 2 additions & 0 deletions e2e/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ beforeAll(async () => {
'.*rainbowme-res.cloudinary.com*',
'.*rainbow-proxy-rpc.rainbowdotme.workers.*',
'.*localhost:8081/assets/src/assets*.',
'.*arc-graphql.rainbowdotme.workers.dev*.',
'.*googleapis.com*.',
]);
});
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ It needs to be an import statement because otherwise it doesn't load properly
likely because of typescript.
*/
import '@walletconnect/react-native-compat';
import { initSentry } from '@/logger/sentry';
import { analytics } from './src/analytics';
import { StartTime } from './src/performance/start-time';
import { PerformanceTracking } from './src/performance/tracking';
import { PerformanceMetrics } from './src/performance/tracking/types/PerformanceMetrics';

initSentry();

analytics.track('Started executing JavaScript bundle');
PerformanceTracking.logDirectly(PerformanceMetrics.loadJSBundle, Date.now() - StartTime.START_TIME);
PerformanceTracking.startMeasuring(PerformanceMetrics.loadRootAppComponent);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@
"webpack-cli": "5.1.4"
},
"resolutions": {
"**/braces": "3.0.3",
"**/async": "2.6.4",
"**/zod": "3.22.3",
"**/file-type": "16.5.4",
Expand Down
15 changes: 5 additions & 10 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import { InitialRouteContext } from '@/navigation/initialRoute';
import Routes from '@/navigation/routesNames';
import { Portal } from '@/react-native-cool-modals/Portal';
import { NotificationsHandler } from '@/notifications/NotificationsHandler';
import { initSentry, sentryRoutingInstrumentation } from '@/logger/sentry';
import { analyticsV2 } from '@/analytics';
import { getOrCreateDeviceId, securelyHashWalletAddress } from '@/analytics/utils';
import { logger, RainbowError } from '@/logger';
Expand All @@ -57,9 +56,10 @@ import { handleReviewPromptAction } from '@/utils/reviewAlert';
import { RemotePromoSheetProvider } from '@/components/remote-promo-sheet/RemotePromoSheetProvider';
import { RemoteCardProvider } from '@/components/cards/remote-cards';
import { initializeRemoteConfig } from '@/model/remoteConfig';
import { IS_DEV } from './env';
import { checkIdentifierOnLaunch } from './model/backup';

if (__DEV__) {
if (IS_DEV) {
reactNativeDisableYellowBox && LogBox.ignoreAllLogs();
(showNetworkRequests || showNetworkResponses) && monitorNetwork(showNetworkRequests, showNetworkResponses);
}
Expand Down Expand Up @@ -218,10 +218,6 @@ class OldApp extends Component {
updateBalancesAfter(isL2 ? 10000 : 5000, isL2, network);
};

handleSentryNavigationIntegration = () => {
sentryRoutingInstrumentation?.registerNavigationContainer(this.navigatorRef);
};

render() {
return (
<Portal>
Expand All @@ -230,7 +226,7 @@ class OldApp extends Component {
<RemotePromoSheetProvider isWalletReady={this.props.walletReady}>
<RemoteCardProvider>
<InitialRouteContext.Provider value={this.state.initialRoute}>
<RoutesComponent onReady={this.handleSentryNavigationIntegration} ref={this.handleNavigatorRef} />
<RoutesComponent ref={this.handleNavigatorRef} />
<PortalConsumer />
</InitialRouteContext.Provider>
</RemoteCardProvider>
Expand All @@ -257,9 +253,7 @@ function Root() {

React.useEffect(() => {
async function initializeApplication() {
await initSentry(); // must be set up immediately
await initializeRemoteConfig();
// must happen immediately, but after Sentry
await migrate();

const isReturningUser = ls.device.get(['isReturningUser']);
Expand Down Expand Up @@ -339,7 +333,7 @@ function Root() {
// init complete, load the rest of the app
setInitializing(false);
})
.catch(e => {
.catch(() => {
logger.error(new RainbowError(`initializeApplication failed`));

// for failure, continue to rest of the app for now
Expand Down Expand Up @@ -369,6 +363,7 @@ function Root() {
);
}

/** Wrapping Root allows Sentry to accurately track startup times */
const RootWithSentry = Sentry.wrap(Root);

const PlaygroundWithReduxStore = () => (
Expand Down
49 changes: 35 additions & 14 deletions src/__swaps__/screens/Swap/components/GasPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@ import {
import { add, subtract } from '@/__swaps__/utils/numbers';
import { opacity } from '@/__swaps__/utils/swaps';
import { ButtonPressAnimation } from '@/components/animations';
import { Box, Inline, Separator, Stack, Text, globalColors, useColorMode, useForegroundColor } from '@/design-system';
import { Bleed, Box, Inline, Separator, Stack, Text, globalColors, useColorMode, useForegroundColor } from '@/design-system';
import { IS_ANDROID } from '@/env';
import { lessThan } from '@/helpers/utilities';
import { useNavigation } from '@/navigation';
import Routes from '@/navigation/routesNames';
import { createRainbowStore } from '@/state/internal/createRainbowStore';
import { useSwapsStore } from '@/state/swaps/swapsStore';
import { upperFirst } from 'lodash';
import { gasUtils } from '@/utils';
import { formatNumber } from '../hooks/formatNumber';
import { GasSettings, getCustomGasSettings, setCustomGasSettings, useCustomGasStore } from '../hooks/useCustomGas';
import { setSelectedGasSpeed, useSelectedGasSpeed } from '../hooks/useSelectedGas';
import { EstimatedSwapGasFee, EstimatedSwapGasFeeSlot } from './EstimatedSwapGasFee';
import { Stall } from './Stall';

const { GAS_TRENDS } = gasUtils;

const MINER_TIP_TYPE = 'minerTip';
const MAX_BASE_FEE_TYPE = 'maxBaseFee';
const HIGH_ALERT = 'HIGH_ALERT';
Expand Down Expand Up @@ -152,9 +155,15 @@ function CurrentBaseFeeSlot({ baseFee, gasTrend }: { baseFee?: string; gasTrend?
const { isDarkMode } = useColorMode();
const { navigate } = useNavigation();

const trendType = 'currentBaseFee' + upperFirst(gasTrend);
const label = useForegroundColor('label');
const labelSecondary = useForegroundColor('labelSecondary');

const chainId = useSwapsStore(s => s.inputAsset?.chainId || ChainId.mainnet);
const { data: baseFee } = useBaseFee({ chainId, select: selectWeiToGwei });
const { data: gasTrend = 'notrend' } = useGasTrend({ chainId });

const trendType = 'currentBaseFee' + upperFirst(gasTrend);

const isEIP1559 = useIsChainEIP1559(chainId);
if (!isEIP1559) return null;

Expand All @@ -170,15 +179,30 @@ function CurrentBaseFeeSlot({ baseFee, gasTrend }: { baseFee?: string; gasTrend?
return (
<Inline horizontalSpace="10px" alignVertical="center" alignHorizontal="justify">
<PressableLabel onPress={onPressLabel}>{i18n.t(i18n.l.gas.current_base_fee)}</PressableLabel>
<Text
align="right"
color={isDarkMode ? 'labelSecondary' : 'label'}
size="15pt"
weight="heavy"
style={{ textTransform: 'capitalize' }}
>
{formatNumber(baseFee || '0')}
</Text>
<Bleed top="16px">
<Stack space="8px">
<Text
align="right"
color={{
custom: GAS_TRENDS[gasTrend].color,
}}
size="13pt"
weight="bold"
style={{ textTransform: 'capitalize' }}
>
{GAS_TRENDS[gasTrend].label}
</Text>
<Text
align="right"
color={{ custom: isDarkMode ? labelSecondary : label }}
size="15pt"
weight="heavy"
style={{ textTransform: 'capitalize' }}
>
{formatNumber(baseFee || '0')}
</Text>
</Stack>
</Bleed>
</Inline>
);
}
Expand Down Expand Up @@ -294,9 +318,6 @@ function MaxTransactionFee() {
<Text color="labelTertiary" weight="semibold" size="15pt">
{i18n.t(i18n.l.gas.max_transaction_fee)}
</Text>
<Text color="labelTertiary" size="13pt" weight="bold">
􀅴
</Text>
</Inline>
</Inline>

Expand Down
2 changes: 1 addition & 1 deletion src/__swaps__/screens/Swap/components/ReviewPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function ReviewPanel() {

const unknown = i18n.t(i18n.l.swap.unknown);

const chainName = useDerivedValue(() => ChainNameDisplay[internalSelectedOutputAsset.value?.chainId ?? ChainId.mainnet]);
const chainName = useDerivedValue(() => ChainNameDisplay[internalSelectedInputAsset.value?.chainId ?? ChainId.mainnet]);

const minimumReceived = useDerivedValue(() => {
if (!SwapInputController.formattedOutputAmount.value || !internalSelectedOutputAsset.value?.symbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { queryClient } from '@/react-query';
import { divWorklet, equalWorklet, greaterThanWorklet, mulWorklet, toFixedWorklet } from '@/__swaps__/safe-math/SafeMath';

function getInitialInputValues(initialSelectedInputAsset: ExtendedAnimatedAssetWithColors | null) {
const initialBalance = Number(initialSelectedInputAsset?.balance.amount) ?? 0;
const initialBalance = Number(initialSelectedInputAsset?.balance.amount) || 0;
const initialNiceIncrement = findNiceIncrement(initialBalance);
const initialDecimalPlaces = countDecimalPlaces(initialNiceIncrement);

Expand Down
6 changes: 4 additions & 2 deletions src/__swaps__/screens/Swap/providers/swap-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {
const selectedOutputChainId = useSharedValue<ChainId>(initialSelectedInputAsset?.chainId || ChainId.mainnet);
const quote = useSharedValue<Quote | CrosschainQuote | QuoteError | null>(null);

const inputProgress = useSharedValue(NavigationSteps.INPUT_ELEMENT_FOCUSED);
const inputProgress = useSharedValue(
initialSelectedOutputAsset && !initialSelectedInputAsset ? NavigationSteps.TOKEN_LIST_FOCUSED : NavigationSteps.INPUT_ELEMENT_FOCUSED
);
const outputProgress = useSharedValue(
initialSelectedOutputAsset ? NavigationSteps.INPUT_ELEMENT_FOCUSED : NavigationSteps.TOKEN_LIST_FOCUSED
);
Expand Down Expand Up @@ -172,7 +174,7 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {
? await getFlashbotsProvider()
: getCachedProviderForNetwork(network);
const providerUrl = provider?.connection?.url;
const connectedToHardhat = isHardHat(providerUrl);
const connectedToHardhat = !!providerUrl && isHardHat(providerUrl);

const selectedGas = getSelectedGas(parameters.chainId);
if (!selectedGas) {
Expand Down
Loading

0 comments on commit ac83432

Please sign in to comment.