Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
33757f0
feat: adds support for custom actions such as paypal
georgeweiler Mar 3, 2026
b7a950e
chore: removes development code
georgeweiler Mar 3, 2026
97686df
feat: code review comments
georgeweiler Mar 4, 2026
3b17f64
chore: installs preview build of ramps controller
georgeweiler Mar 4, 2026
826e3a7
Merge branch 'main' of github.com:MetaMask/metamask-mobile into v2-cu…
georgeweiler Mar 4, 2026
2be7c8d
Merge branch 'main' of github.com:MetaMask/metamask-mobile into v2-cu…
georgeweiler Mar 4, 2026
4b43c56
chore: installs preview for ramps-controller
georgeweiler Mar 4, 2026
c5c1c83
[skip ci] Bump version number to 3890
metamaskbot Mar 4, 2026
f2d8bc1
[skip ci] Bump version number to 3892
metamaskbot Mar 4, 2026
6271a11
fix: use deep link redirect and navigate to order details after PayPa…
amitabh94 Mar 6, 2026
bd3c409
fix: override redirectUrl with deep link for external browser providers
amitabh94 Mar 6, 2026
69bedfa
fix: skip order details navigation when user cancels external browser
amitabh94 Mar 6, 2026
8dc210d
fix: always override redirectUrl on buyURL before fetching widget
amitabh94 Mar 6, 2026
e506bb1
chore: add temporary debug logging for PayPal redirect flow
amitabh94 Mar 6, 2026
63b75e2
chore: add comprehensive debug logging for PayPal redirect flow
amitabh94 Mar 6, 2026
bc012ac
fix: pass extracted orderCode to OrderDetails instead of full orderId
amitabh94 Mar 6, 2026
2ebe31d
chore: add DEV-only mock bypass for PayPal external browser flow
amitabh94 Mar 6, 2026
2fdfc44
chore: merge with main branch
georgeweiler Mar 9, 2026
f75705b
Merge branch 'v2-custom-actions' of github.com:MetaMask/metamask-mobi…
georgeweiler Mar 9, 2026
4f0a068
chore: debug instrumentation
georgeweiler Mar 9, 2026
93003e7
feat: hide precreated and expired orders from orders list
georgeweiler Mar 9, 2026
479f678
fix: OrderDetails hydration fallback and remove debug instrumentation
lorenzosantos Mar 9, 2026
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
5 changes: 5 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,13 @@ android {
applicationId "io.metamask"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
<<<<<<< HEAD
versionName "7.69.0"
versionCode 3892
=======
versionName "7.70.0"
versionCode 3607
>>>>>>> 1242530285d27aa5c0f2a7b7b53cc417231b3d58
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unresolved Git Merge Conflict in Build File

High Severity

The file contains raw git merge conflict markers (<<<<<<< HEAD, =======, >>>>>>>) for the versionName and versionCode fields. This is a Gradle syntax error that will cause every Android build to fail immediately. The conflict between version 7.69.0/code 3892 (HEAD) and 7.70.0/code 3607 (the other branch) was never resolved before committing.

Fix in Cursor Fix in Web

testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders.MM_BRANCH_KEY_TEST = "$System.env.MM_BRANCH_KEY_TEST"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const mockUseRampsControllerInitialValues: ReturnType<
paymentMethodsLoading: false,
paymentMethodsError: null,
getQuotes: jest.fn(),
getWidgetUrl: jest.fn(),
getBuyWidgetData: jest.fn(),
orders: [],
getOrderById: jest.fn(),
addOrder: jest.fn(),
Expand Down
57 changes: 35 additions & 22 deletions app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ const mockNavigate = jest.fn();
const mockSetOptions = jest.fn();
const mockGoBack = jest.fn();
const mockSetParams = jest.fn();
const mockGetWidgetUrl = jest.fn<
Promise<string | null>,
const mockGetBuyWidgetData = jest.fn<
Promise<{ url: string; orderId?: string | null } | null>,
[quote: Record<string, unknown>]
>(async (quote) => {
const buyUrl = (quote as { quote?: { buyURL: string } })?.quote?.buyURL;
if (!buyUrl) return null;
// Simulate the fetch behavior
return 'https://global.transak.com/?apiKey=test';
return {
url: 'https://global.transak.com/?apiKey=test',
orderId: null,
};
});

const MOCK_ASSET_ID =
Expand Down Expand Up @@ -215,12 +217,15 @@ let mockQuotesData: {
let mockQuotesLoading = false;
let mockQuotesError: string | null = null;

const mockAddPrecreatedOrder = jest.fn();

jest.mock('../../hooks/useRampsController', () => ({
useRampsController: () => ({
userRegion: mockUserRegion,
selectedProvider: mockSelectedProvider,
selectedToken: mockTokens?.allTokens?.[0] ?? null,
getWidgetUrl: mockGetWidgetUrl,
getBuyWidgetData: mockGetBuyWidgetData,
addPrecreatedOrder: mockAddPrecreatedOrder,
paymentMethodsLoading: false,
selectedPaymentMethod: mockSelectedPaymentMethod,
}),
Expand Down Expand Up @@ -708,9 +713,10 @@ describe('BuildQuote', () => {
const continueButton = getByTestId('build-quote-continue-button');
expect(continueButton).not.toBeDisabled();

mockGetWidgetUrl.mockResolvedValue(
'https://global.transak.com/?apiKey=test',
);
mockGetBuyWidgetData.mockResolvedValue({
url: 'https://global.transak.com/?apiKey=test',
orderId: null,
});

await act(async () => {
fireEvent.press(continueButton);
Expand Down Expand Up @@ -765,9 +771,10 @@ describe('BuildQuote', () => {
error: [],
customActions: [],
};
mockGetWidgetUrl.mockResolvedValue(
'https://global.transak.com/?apiKey=test',
);
mockGetBuyWidgetData.mockResolvedValue({
url: 'https://global.transak.com/?apiKey=test',
orderId: null,
});

const { getByTestId } = renderWithTheme(<BuildQuote />);

Expand Down Expand Up @@ -981,7 +988,7 @@ describe('BuildQuote', () => {

it('logs error when aggregator provider has no URL', async () => {
const mockLogger = jest.spyOn(Logger, 'error');
mockGetWidgetUrl.mockResolvedValue(null);
mockGetBuyWidgetData.mockResolvedValue(null);

const mockQuote = {
provider: '/providers/mercuryo',
Expand Down Expand Up @@ -1083,7 +1090,7 @@ describe('BuildQuote', () => {
});

expect(mockNavigate).not.toHaveBeenCalled();
expect(mockGetWidgetUrl).not.toHaveBeenCalled();
expect(mockGetBuyWidgetData).not.toHaveBeenCalled();
});

it('does not navigate when quote payment method does not match selected payment method', async () => {
Expand Down Expand Up @@ -1129,7 +1136,7 @@ describe('BuildQuote', () => {
});

expect(mockNavigate).not.toHaveBeenCalled();
expect(mockGetWidgetUrl).not.toHaveBeenCalled();
expect(mockGetBuyWidgetData).not.toHaveBeenCalled();
});

it('does not navigate when quote has payment method but selectedPaymentMethod is missing', async () => {
Expand Down Expand Up @@ -1172,12 +1179,14 @@ describe('BuildQuote', () => {
});

expect(mockNavigate).not.toHaveBeenCalled();
expect(mockGetWidgetUrl).not.toHaveBeenCalled();
expect(mockGetBuyWidgetData).not.toHaveBeenCalled();
});

it('logs error when getWidgetUrl throws', async () => {
it('logs error when getBuyWidgetData throws', async () => {
const mockLogger = jest.spyOn(Logger, 'error');
mockGetWidgetUrl.mockRejectedValue(new Error('Widget URL fetch failed'));
mockGetBuyWidgetData.mockRejectedValue(
new Error('Widget URL fetch failed'),
);

const mockQuote = {
provider: '/providers/mercuryo',
Expand Down Expand Up @@ -1264,7 +1273,7 @@ describe('BuildQuote', () => {
});

expect(mockNavigate).not.toHaveBeenCalled();
expect(mockGetWidgetUrl).not.toHaveBeenCalled();
expect(mockGetBuyWidgetData).not.toHaveBeenCalled();
expect(mockTransakCheckExistingToken).not.toHaveBeenCalled();
});

Expand Down Expand Up @@ -1298,7 +1307,10 @@ describe('BuildQuote', () => {
error: [],
customActions: [],
};
mockGetWidgetUrl.mockResolvedValue('https://example.com/widget');
mockGetBuyWidgetData.mockResolvedValue({
url: 'https://example.com/widget',
orderId: null,
});

const { getByTestId } = renderWithTheme(<BuildQuote />);

Expand Down Expand Up @@ -1351,9 +1363,10 @@ describe('BuildQuote', () => {
customActions: [],
};

mockGetWidgetUrl.mockResolvedValue(
'https://global.transak.com/?apiKey=test',
);
mockGetBuyWidgetData.mockResolvedValue({
url: 'https://global.transak.com/?apiKey=test',
orderId: null,
});

const { getByTestId } = renderWithTheme(<BuildQuote />);

Expand Down
Loading
Loading