Skip to content
Merged
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
4 changes: 2 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<!-- Android < 12 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />

<!-- Bluetooth permissions: Android API >= 31 (Android 12)-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>

<uses-sdk tools:overrideLibrary="com.tectiv3.aes" />

Expand Down
2 changes: 0 additions & 2 deletions app/components/UI/Perps/__mocks__/serviceMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ export const createMockPerpsControllerState = (
): PerpsControllerState => ({
activeProvider: 'hyperliquid',
isTestnet: false,
connectionStatus: 'connected',
initializationState: 'initialized' as InitializationState,
initializationError: null,
initializationAttempts: 0,
accountState: null,
positions: [],
perpsBalances: {},
depositInProgress: false,
lastDepositTransactionId: null,
Expand Down
14 changes: 0 additions & 14 deletions app/components/UI/Perps/controllers/PerpsController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,9 +483,7 @@ describe('PerpsController', () => {
it('initializes with default state', () => {
// Constructor no longer auto-starts initialization (moved to Engine.ts)
expect(controller.state.activeProvider).toBe('hyperliquid');
expect(controller.state.positions).toEqual([]);
expect(controller.state.accountState).toBeNull();
expect(controller.state.connectionStatus).toBe('disconnected');
expect(controller.state.initializationState).toBe('uninitialized'); // Waits for explicit initialization
expect(controller.state.initializationError).toBeNull();
expect(controller.state.initializationAttempts).toBe(0); // Not started yet
Expand Down Expand Up @@ -1480,18 +1478,6 @@ describe('PerpsController', () => {
await controller.disconnect();

expect(mockProvider.disconnect).toHaveBeenCalled();
expect(controller.state.connectionStatus).toBe('disconnected');
});

it('handles connection status from state', () => {
// Test that we can access connection status from controller state
expect(controller.state.connectionStatus).toBe('disconnected');

// Test that the state is accessible and has the expected default value
expect(typeof controller.state.connectionStatus).toBe('string');
expect(['connected', 'disconnected', 'connecting']).toContain(
controller.state.connectionStatus,
);
});
});

Expand Down
20 changes: 0 additions & 20 deletions app/components/UI/Perps/controllers/PerpsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ export type PerpsControllerState = {
// Active provider
activeProvider: string;
isTestnet: boolean; // Dev toggle for testnet
connectionStatus: 'disconnected' | 'connecting' | 'connected';

// Initialization state machine
initializationState: InitializationState;
Expand All @@ -139,9 +138,6 @@ export type PerpsControllerState = {
// Account data (persisted) - using HyperLiquid property names
accountState: AccountState | null;

// Current positions
positions: Position[];

// Perps balances per provider for portfolio display (historical data)
perpsBalances: {
[provider: string]: {
Expand Down Expand Up @@ -279,12 +275,10 @@ export type PerpsControllerState = {
export const getDefaultPerpsControllerState = (): PerpsControllerState => ({
activeProvider: 'hyperliquid',
isTestnet: false, // Default to mainnet
connectionStatus: 'disconnected',
initializationState: InitializationState.UNINITIALIZED,
initializationError: null,
initializationAttempts: 0,
accountState: null,
positions: [],
perpsBalances: {},
depositInProgress: false,
lastDepositResult: null,
Expand Down Expand Up @@ -331,12 +325,6 @@ const metadata: StateMetadata<PerpsControllerState> = {
includeInDebugSnapshot: false,
usedInUi: true,
},
positions: {
includeInStateLogs: true,
persist: false,
includeInDebugSnapshot: false,
usedInUi: true,
},
perpsBalances: {
includeInStateLogs: true,
persist: true,
Expand All @@ -355,12 +343,6 @@ const metadata: StateMetadata<PerpsControllerState> = {
includeInDebugSnapshot: false,
usedInUi: true,
},
connectionStatus: {
includeInStateLogs: true,
persist: false,
includeInDebugSnapshot: false,
usedInUi: true,
},
initializationState: {
includeInStateLogs: true,
persist: false,
Expand Down Expand Up @@ -1900,7 +1882,6 @@ export class PerpsController extends BaseController<

this.update((state) => {
state.isTestnet = !state.isTestnet;
state.connectionStatus = 'disconnected';
});

const newNetwork = this.state.isTestnet ? 'testnet' : 'mainnet';
Expand Down Expand Up @@ -1951,7 +1932,6 @@ export class PerpsController extends BaseController<

this.update((state) => {
state.activeProvider = providerId;
state.connectionStatus = 'disconnected';
});

return { success: true, providerId };
Expand Down
46 changes: 23 additions & 23 deletions app/components/UI/Perps/hooks/usePerpsSelector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ describe('usePerpsSelector', () => {
expect(result.current).toBe(false);
});

it('should work with different selector functions', () => {
it('works with different selector functions', () => {
// Arrange
const mockState: PerpsControllerState = {
isFirstTimeUser: {
testnet: true,
mainnet: true,
},
isEligible: true,
connectionStatus: 'connected',
positions: [{ coin: 'ETH' }],
isTestnet: false,
activeProvider: 'hyperliquid',
} as PerpsControllerState;

mockUseSelector.mockImplementation((selectorFn) =>
Expand All @@ -82,11 +82,10 @@ describe('usePerpsSelector', () => {
state?.isFirstTimeUser.mainnet ?? false;
const isEligibleSelector = (state: PerpsControllerState | undefined) =>
state?.isEligible ?? false;
const connectionStatusSelector = (
state: PerpsControllerState | undefined,
) => state?.connectionStatus ?? 'disconnected';
const positionsCountSelector = (state: PerpsControllerState | undefined) =>
state?.positions?.length ?? 0;
const isTestnetSelector = (state: PerpsControllerState | undefined) =>
state?.isTestnet ?? false;
const activeProviderSelector = (state: PerpsControllerState | undefined) =>
state?.activeProvider ?? 'hyperliquid';

// Act & Assert
const { result: isFirstTimeUserResult } = renderHook(() =>
Expand All @@ -99,24 +98,24 @@ describe('usePerpsSelector', () => {
);
expect(isEligibleResult.current).toBe(true);

const { result: connectionStatusResult } = renderHook(() =>
usePerpsSelector(connectionStatusSelector),
const { result: isTestnetResult } = renderHook(() =>
usePerpsSelector(isTestnetSelector),
);
expect(connectionStatusResult.current).toBe('connected');
expect(isTestnetResult.current).toBe(false);

const { result: positionsCountResult } = renderHook(() =>
usePerpsSelector(positionsCountSelector),
const { result: activeProviderResult } = renderHook(() =>
usePerpsSelector(activeProviderSelector),
);
expect(positionsCountResult.current).toBe(1);
expect(activeProviderResult.current).toBe('hyperliquid');
});

it('should return computed values from selector functions', () => {
it('returns computed values from selector functions', () => {
// Arrange
const mockState: PerpsControllerState = {
positions: [
{ coin: 'ETH', size: '1.5' },
{ coin: 'BTC', size: '0.1' },
],
watchlistMarkets: {
testnet: ['ETH', 'BTC'],
mainnet: ['SOL', 'DOGE'],
},
} as PerpsControllerState;

mockUseSelector.mockImplementation((selectorFn) =>
Expand All @@ -125,16 +124,17 @@ describe('usePerpsSelector', () => {
}),
);

const positionCoinsSelector = (state: PerpsControllerState | undefined) =>
state?.positions?.map((p) => p.coin) ?? [];
const mainnetWatchlistSelector = (
state: PerpsControllerState | undefined,
) => state?.watchlistMarkets?.mainnet ?? [];

// Act
const { result } = renderHook(() =>
usePerpsSelector(positionCoinsSelector),
usePerpsSelector(mainnetWatchlistSelector),
);

// Assert
expect(result.current).toEqual(['ETH', 'BTC']);
expect(result.current).toEqual(['SOL', 'DOGE']);
});

it('should handle complex nested state selection', () => {
Expand Down
101 changes: 101 additions & 0 deletions app/components/Views/ChoosePassword/ChoosePassword.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { StyleSheet, Platform } from 'react-native';
import { Theme } from '../../../util/theme/models';
import Device from '../../../util/device';

const createStyles = (colors: Theme['colors']) =>
StyleSheet.create({
mainWrapper: {
backgroundColor: colors.background.default,
flex: 1,
},
wrapper: {
flex: 1,
paddingHorizontal: 16,
},
container: {
flex: 1,
flexDirection: 'column',
},
loadingWrapper: {
paddingHorizontal: 16,
alignItems: 'center',
display: 'flex',
justifyContent: 'flex-start',
alignContent: 'center',
flex: 1,
rowGap: 24,
},
foxWrapper: {
width: Device.isMediumDevice() ? 180 : 220,
height: Device.isMediumDevice() ? 180 : 220,
},
image: {
alignSelf: 'center',
width: Device.isMediumDevice() ? 180 : 220,
height: Device.isMediumDevice() ? 180 : 220,
},
loadingTextContainer: {
display: 'flex',
flexDirection: 'column',
rowGap: 4,
alignItems: 'center',
justifyContent: 'center',
},
field: {
position: 'relative',
flexDirection: 'column',
gap: 8,
},
ctaWrapper: {
width: '100%',
flexDirection: 'column',
rowGap: 18,
marginBottom: Platform.select({
ios: 16,
android: 24,
default: 16,
}),
},
learnMoreContainer: {
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'flex-start',
gap: 8,
marginTop: 8,
backgroundColor: colors.background.section,
borderRadius: 8,
padding: 16,
},
learnMoreTextContainer: {
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'flex-start',
gap: 1,
flexWrap: 'wrap',
width: '90%',
marginTop: -6,
},
headerLeft: {
marginLeft: 16,
},
headerRight: {
marginRight: 16,
},
passwordContainer: {
flexDirection: 'column',
rowGap: 16,
flexGrow: 1,
},
label: {
marginBottom: -4,
},
checkbox: {
alignItems: 'flex-start',
},
passwordContainerTitle: {
flexDirection: 'column',
rowGap: 4,
},
});

export default createStyles;
14 changes: 14 additions & 0 deletions app/components/Views/ChoosePassword/ChoosePassword.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { TraceContext } from '../../../util/trace';

export interface ChoosePasswordRouteParams {
isFromLogin?: boolean;
oauthLoginSuccess?: boolean;
onboardingTraceCtx?: TraceContext;
provider?: string;
previous_screen?: string;
}

export interface BiometryType {
availableBiometryType: string | null;
currentAuthType: string;
}
Loading
Loading