Skip to content

Commit 6add80c

Browse files
authored
Merge branch 'main' into mikesposito/deps/smart-transactions-controller
2 parents d62ee40 + 5f8aafa commit 6add80c

File tree

69 files changed

+3300
-1892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3300
-1892
lines changed

app/component-library/components/Icons/Icon/Icon.assets.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ import mapSVG from './assets/map.svg';
150150
import menuSVG from './assets/menu.svg';
151151
import messagequestionSVG from './assets/message-question.svg';
152152
import messagesSVG from './assets/messages.svg';
153+
import metamaskfoxoutlineSVG from './assets/metamask-fox-outline.svg';
153154
import micSVG from './assets/mic.svg';
154155
import minusboldSVG from './assets/minus-bold.svg';
155156
import minussquareSVG from './assets/minus-square.svg';
@@ -427,6 +428,7 @@ export const assetByIconName: AssetByIconName = {
427428
[IconName.Menu]: menuSVG,
428429
[IconName.MessageQuestion]: messagequestionSVG,
429430
[IconName.Messages]: messagesSVG,
431+
[IconName.MetamaskFoxOutline]: metamaskfoxoutlineSVG,
430432
[IconName.Mic]: micSVG,
431433
[IconName.MinusBold]: minusboldSVG,
432434
[IconName.MinusSquare]: minussquareSVG,

app/component-library/components/Icons/Icon/Icon.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ export enum IconName {
220220
Menu = 'Menu',
221221
MessageQuestion = 'MessageQuestion',
222222
Messages = 'Messages',
223+
MetamaskFoxOutline = 'MetamaskFoxOutline',
223224
Mic = 'Mic',
224225
MinusBold = 'MinusBold',
225226
MinusSquare = 'MinusSquare',
Lines changed: 1 addition & 0 deletions
Loading

app/component-library/components/Navigation/TabBar/TabBar.constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const ICON_BY_TAB_BAR_ICON_KEY: IconByTabBarIconKey = {
1212
[TabBarIconKey.Trade]: IconName.Add,
1313
[TabBarIconKey.Activity]: IconName.Activity,
1414
[TabBarIconKey.Setting]: IconName.Setting,
15-
[TabBarIconKey.Rewards]: IconName.Star,
15+
[TabBarIconKey.Rewards]: IconName.MetamaskFoxOutline,
1616
};
1717

1818
export const LABEL_BY_TAB_BAR_ICON_KEY = {

app/component-library/components/Skeleton/Skeleton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const Skeleton: React.FC<SkeletonProps> = ({
5252

5353
useEffect(() => {
5454
// Only start animation if no children are present or if children should be hidden
55-
if (!isE2E && (!children || hideChildren)) {
55+
if (!isE2E && !process.env.JEST_WORKER_ID && (!children || hideChildren)) {
5656
startAnimation();
5757
}
5858

app/components/UI/Perps/Views/PerpsClosePositionView/PerpsClosePositionView.test.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -442,16 +442,14 @@ describe('PerpsClosePositionView', () => {
442442
true,
443443
);
444444

445-
// Assert - receiveAmount = (initialMargin + effectivePnL) - fees
446-
// effectivePnL = (150 - 100) * 1 = 50
447-
// effectiveMargin = 1000 + 50 = 1050
448-
// receiveAmount = 1050 - 50 = 1000
445+
// Assert - receiveAmount = initialMargin - fees (P&L is shown separately in UI)
446+
// receiveAmount = 1000 - 50 = 950
449447
const receiveText = getByText(
450448
strings('perps.close_position.you_receive'),
451449
);
452450
expect(receiveText).toBeDefined();
453-
// Look for 1000 in the display (margin + P&L - fees)
454-
expect(getByText(/1,000/)).toBeDefined();
451+
// Look for 950 in the display (margin - fees, P&L shown separately)
452+
expect(getByText('$950.00')).toBeDefined();
455453
});
456454

457455
it('calculates receive amount correctly for partial close percentages', () => {
@@ -488,16 +486,14 @@ describe('PerpsClosePositionView', () => {
488486
true,
489487
);
490488

491-
// For 100% close (default):
492-
// effectivePnL = (75 - 100) * 2 = -50
493-
// effectiveMargin = 2000 + (-50) = 1950
494-
// receiveAmount = 1950 - 25 = 1925
489+
// For 100% close (default) with new calculation:
490+
// receiveAmount = initialMargin - fees = 2000 - 25 = 1975
495491
const receiveText = getByText(
496492
strings('perps.close_position.you_receive'),
497493
);
498494
expect(receiveText).toBeDefined();
499-
// Look for 1925 in the display (effective margin - fees)
500-
expect(getByText(/1,925/)).toBeDefined();
495+
// Look for 1975 in the display (initial margin - fees)
496+
expect(getByText(/1,975/)).toBeDefined();
501497
});
502498
});
503499

app/components/UI/Perps/Views/PerpsClosePositionView/PerpsClosePositionView.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ const PerpsClosePositionView: React.FC = () => {
168168
// Use the actual initial margin from the position
169169
const initialMargin = parseFloat(position.marginUsed);
170170

171-
// Calculate effective margin (initial margin + P&L at effective price)
172-
const effectiveMargin = initialMargin + effectivePnL;
173-
174171
// Use unrealized PnL from position for current market price (for reference/tracking)
175172
const pnl = parseFloat(position.unrealizedPnl);
176173

@@ -195,9 +192,10 @@ const PerpsClosePositionView: React.FC = () => {
195192
orderAmount: closingValue.toString(),
196193
});
197194

198-
// Calculate what user will receive (initial margin + P&L at effective price - fees)
195+
// Calculate what user will receive (initial margin - fees)
196+
// P&L is already shown separately in the margin section as "includes P&L"
199197
const receiveAmount =
200-
(closePercentage / 100) * effectiveMargin - feeResults.totalFee;
198+
(closePercentage / 100) * initialMargin - feeResults.totalFee;
201199

202200
// Get minimum order amount for this asset
203201
const { minimumOrderAmount } = useMinimumOrderAmount({
@@ -446,7 +444,7 @@ const PerpsClosePositionView: React.FC = () => {
446444
</View>
447445
<View style={styles.summaryValue}>
448446
<Text variant={TextVariant.BodyMD}>
449-
{formatPrice(effectiveMargin * (closePercentage / 100), {
447+
{formatPrice(initialMargin * (closePercentage / 100), {
450448
maximumDecimals: 2,
451449
})}
452450
</Text>
@@ -515,10 +513,7 @@ const PerpsClosePositionView: React.FC = () => {
515513
</TouchableOpacity>
516514
</View>
517515
<View style={styles.summaryValue}>
518-
<Text
519-
variant={TextVariant.BodyMD}
520-
color={receiveAmount > 0 ? TextColor.Success : TextColor.Default}
521-
>
516+
<Text variant={TextVariant.BodyMD} color={TextColor.Default}>
522517
{formatPrice(receiveAmount, { maximumDecimals: 2 })}
523518
</Text>
524519
</View>

app/components/UI/Perps/components/PerpsFeesDisplay/PerpsFeesDisplay.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const PerpsFeesDisplay: React.FC<PerpsFeesDisplayProps> = ({
3636
</View>
3737
</TagColored>
3838
) : null}
39-
<Text variant={variant} color={TextColor.Alternative}>
39+
<Text variant={variant} color={TextColor.Default}>
4040
{formatFeeText}
4141
</Text>
4242
</View>

app/components/UI/Perps/components/PerpsTPSLBottomSheet/PerpsTPSLBottomSheet.styles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ export const createStyles = (colors: Theme['colors']) =>
185185
paddingHorizontal: 8,
186186
width: '100%',
187187
},
188-
keypadDismissButton: {
188+
doneButton: {
189189
width: '100%',
190-
marginVertical: 12,
190+
marginBottom: 8,
191191
},
192192
});

app/components/UI/Perps/components/PerpsTPSLBottomSheet/PerpsTPSLBottomSheet.test.tsx

Lines changed: 114 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -299,44 +299,118 @@ jest.mock('../../../../../component-library/components/Texts/Text', () => {
299299
};
300300
});
301301

302-
// Mock Button enums
303-
jest.mock('../../../../../component-library/components/Buttons/Button', () => ({
304-
ButtonSize: {
305-
Lg: 'Lg',
306-
},
307-
ButtonVariants: {
308-
Primary: 'Primary',
309-
},
310-
}));
302+
// Mock Button component and enums
303+
jest.mock('../../../../../component-library/components/Buttons/Button', () => {
304+
const { TouchableOpacity, Text } = jest.requireActual('react-native');
305+
306+
const MockButton = ({
307+
label,
308+
onPress,
309+
isDisabled,
310+
loading,
311+
style,
312+
}: {
313+
label: string;
314+
onPress: () => void;
315+
isDisabled?: boolean;
316+
loading?: boolean;
317+
style?: unknown;
318+
}) => (
319+
<TouchableOpacity
320+
style={style}
321+
onPress={onPress}
322+
disabled={isDisabled || loading}
323+
>
324+
<Text>{loading ? 'Loading...' : label}</Text>
325+
</TouchableOpacity>
326+
);
327+
328+
return {
329+
__esModule: true,
330+
default: MockButton,
331+
ButtonSize: {
332+
Lg: 'Lg',
333+
},
334+
ButtonVariants: {
335+
Primary: 'Primary',
336+
},
337+
};
338+
});
311339

312340
// Mock Keypad component
313341
jest.mock('../../../../../components/Base/Keypad', () => {
314342
const { View, Text, TouchableOpacity } = jest.requireActual('react-native');
343+
344+
// Mock compound component structure
345+
const MockKeypadRow = ({ children }: { children: React.ReactNode }) => (
346+
<View>{children}</View>
347+
);
348+
349+
const MockKeypadButton = ({
350+
children,
351+
onPress,
352+
}: {
353+
children: React.ReactNode;
354+
onPress?: () => void;
355+
}) => (
356+
<TouchableOpacity onPress={onPress}>
357+
<Text>{children}</Text>
358+
</TouchableOpacity>
359+
);
360+
361+
const MockKeypadDeleteButton = ({
362+
onPress,
363+
onLongPress,
364+
testID,
365+
}: {
366+
onPress?: () => void;
367+
onLongPress?: () => void;
368+
testID?: string;
369+
}) => (
370+
<TouchableOpacity
371+
testID={testID}
372+
onPress={onPress}
373+
onLongPress={onLongPress}
374+
>
375+
<Text>Del</Text>
376+
</TouchableOpacity>
377+
);
378+
379+
const MockKeypad = ({
380+
value,
381+
onChange,
382+
currency,
383+
decimals,
384+
children,
385+
}: {
386+
value: string;
387+
onChange: ({ value }: { value: string; valueAsNumber: number }) => void;
388+
currency: string;
389+
decimals: number;
390+
children?: React.ReactNode;
391+
}) => (
392+
<View testID="keypad">
393+
<Text testID="keypad-value">{value}</Text>
394+
<Text testID="keypad-currency">{currency}</Text>
395+
<Text testID="keypad-decimals">{decimals}</Text>
396+
<TouchableOpacity
397+
testID="keypad-test-button"
398+
onPress={() => onChange({ value: '123.45', valueAsNumber: 123.45 })}
399+
>
400+
<Text>Test Keypad Input</Text>
401+
</TouchableOpacity>
402+
{children}
403+
</View>
404+
);
405+
406+
// Attach sub-components to main component
407+
MockKeypad.Row = MockKeypadRow;
408+
MockKeypad.Button = MockKeypadButton;
409+
MockKeypad.DeleteButton = MockKeypadDeleteButton;
410+
315411
return {
316412
__esModule: true,
317-
default: ({
318-
value,
319-
onChange,
320-
currency,
321-
decimals,
322-
}: {
323-
value: string;
324-
onChange: ({ value }: { value: string; valueAsNumber: number }) => void;
325-
currency: string;
326-
decimals: number;
327-
}) => (
328-
<View testID="keypad">
329-
<Text testID="keypad-value">{value}</Text>
330-
<Text testID="keypad-currency">{currency}</Text>
331-
<Text testID="keypad-decimals">{decimals}</Text>
332-
<TouchableOpacity
333-
testID="keypad-test-button"
334-
onPress={() => onChange({ value: '123.45', valueAsNumber: 123.45 })}
335-
>
336-
<Text>Test Keypad Input</Text>
337-
</TouchableOpacity>
338-
</View>
339-
),
413+
default: MockKeypad,
340414
};
341415
});
342416

@@ -368,6 +442,10 @@ jest.mock('./PerpsTPSLBottomSheet.styles', () => ({
368442
helperText: { marginTop: 4 },
369443
keypadContainer: { paddingHorizontal: 16, paddingVertical: 8 },
370444
scrollContent: { flex: 1 },
445+
doneButton: {
446+
width: '100%',
447+
marginBottom: 8,
448+
},
371449
}),
372450
}));
373451

@@ -894,7 +972,7 @@ describe('PerpsTPSLBottomSheet', () => {
894972
render(<PerpsTPSLBottomSheet {...defaultProps} />);
895973

896974
// Assert - Component renders correctly even with validation errors
897-
const confirmButton = screen.getByText('perps.tpsl.set');
975+
const confirmButton = screen.getByText('perps.tpsl.done');
898976
expect(confirmButton).toBeOnTheScreen();
899977

900978
// Note: The actual button disable behavior depends on the component implementation
@@ -1076,7 +1154,7 @@ describe('PerpsTPSLBottomSheet', () => {
10761154
<PerpsTPSLBottomSheet {...defaultProps} onConfirm={mockOnConfirm} />,
10771155
);
10781156

1079-
const confirmButton = screen.getByText('perps.tpsl.set');
1157+
const confirmButton = screen.getByText('perps.tpsl.done');
10801158

10811159
// Act
10821160
fireEvent.press(confirmButton);
@@ -1092,7 +1170,7 @@ describe('PerpsTPSLBottomSheet', () => {
10921170
<PerpsTPSLBottomSheet {...defaultProps} onConfirm={mockOnConfirm} />,
10931171
);
10941172

1095-
const confirmButton = screen.getByText('perps.tpsl.set');
1173+
const confirmButton = screen.getByText('perps.tpsl.done');
10961174

10971175
// Act
10981176
fireEvent.press(confirmButton);
@@ -1106,7 +1184,7 @@ describe('PerpsTPSLBottomSheet', () => {
11061184
const mockOnClose = jest.fn();
11071185
render(<PerpsTPSLBottomSheet {...defaultProps} onClose={mockOnClose} />);
11081186

1109-
const confirmButton = screen.getByText('perps.tpsl.set');
1187+
const confirmButton = screen.getByText('perps.tpsl.done');
11101188

11111189
// Act
11121190
fireEvent.press(confirmButton);

0 commit comments

Comments
 (0)