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
62 changes: 28 additions & 34 deletions .github/workflows/update-latest-build-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,39 @@
##############################################################################################
name: Update Latest Build Version


on:
workflow_dispatch:
inputs:
base-branch:
description: 'The base branch, tag, or SHA for git operations and the pull request.'
required: true
jobs:
generate-build-version:
uses: MetaMask/metamask-mobile-build-version/.github/workflows/metamask-mobile-build-version.yml@v0.2.0
permissions:
id-token: write
generate-build-version:
uses: MetaMask/metamask-mobile-build-version/.github/workflows/metamask-mobile-build-version.yml@v0.2.0
permissions:
id-token: write

bump-version:
runs-on: ubuntu-latest
needs: generate-build-version
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ inputs.base-branch }}
token: ${{ secrets.PR_TOKEN }}

bump-version:
runs-on: ubuntu-latest
needs: generate-build-version
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ inputs.base-branch }}
token: ${{ secrets.PR_TOKEN }}

- name: Bump script
env:
HEAD_REF: ${{ inputs.base-branch }}
run: |
./scripts/set-build-version.sh ${{ needs.generate-build-version.outputs.build-version }}
git diff
git config user.name metamaskbot
git config user.email metamaskbot@users.noreply.github.com
git add bitrise.yml
git add package.json
git add ios/MetaMask.xcodeproj/project.pbxproj
git add android/app/build.gradle
git commit -m "Bump version number to ${{ needs.generate-build-version.outputs.build-version }}"
git push origin HEAD:"$HEAD_REF" --force


- name: Bump script
env:
HEAD_REF: ${{ inputs.base-branch }}
run: |
./scripts/set-build-version.sh ${{ needs.generate-build-version.outputs.build-version }}
git diff
git config user.name metamaskbot
git config user.email metamaskbot@users.noreply.github.com
git add bitrise.yml
git add package.json
git add ios/MetaMask.xcodeproj/project.pbxproj
git add android/app/build.gradle
git commit -m "Bump version number to ${{ needs.generate-build-version.outputs.build-version }}"
git push origin HEAD:"$HEAD_REF" --force-with-lease
3 changes: 3 additions & 0 deletions ReactotronConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Reactotron, { networking } from 'reactotron-react-native';

Reactotron.configure().use(networking()).connect();
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ const InstallSnapApproval = () => {
const connectSnapIds = getConnectSnapIds(approvalRequest, currentPermissions);

const snapId = installSnapId ?? connectSnapIds[0];

if (!snapId) {
return null;
}

const snapName = getSnapMetadata(snapId).name;

// TODO: This component should support connecting to multiple Snaps at once.
Expand Down
1 change: 0 additions & 1 deletion app/core/AppStateEventListener.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ describe('AppStateEventListener', () => {
.mockReturnValue({} as unknown as ReduxStore);
const mockAttribution = {
attributionId: 'test123',
utm: 'test_utm',
utm_source: 'source',
utm_medium: 'medium',
utm_campaign: 'campaign',
Expand Down
6 changes: 3 additions & 3 deletions app/core/AppStateEventListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ export class AppStateEventListener {
MetaMetricsEvents.APP_OPENED,
);
if (attribution) {
const { attributionId, utm, ...utmParams } = attribution;
const { attributionId, ...utmParams } = attribution;
DevLogger.log(
`AppStateManager:: processAppStateChange:: sending event 'APP_OPENED' attributionId=${attribution.attributionId} utm=${attribution.utm}`,
`AppStateManager:: processAppStateChange:: sending event 'APP_OPENED' attributionId=${attribution.attributionId}`,
utmParams,
);
appOpenedEventBuilder.addProperties({ attributionId, ...utmParams });
appOpenedEventBuilder.addProperties({ ...attribution });
}
metrics.trackEvent(appOpenedEventBuilder.build());
} catch (error) {
Expand Down
126 changes: 80 additions & 46 deletions app/core/DeeplinkManager/ParseManager/extractURLParams.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import qs from 'qs';
import { Alert } from 'react-native';
import UrlParser from 'url-parse';
import { strings } from '../../../../locales/i18n';
import { PROTOCOLS } from '../../../constants/deeplinks';
import extractURLParams from './extractURLParams';
Expand All @@ -9,29 +8,21 @@ jest.mock('qs', () => ({
parse: jest.fn(),
}));

jest.mock('url-parse', () => {
const mockUrlParser = jest.fn();

return {
__esModule: true,
default: mockUrlParser,
};
});

jest.mock('react-native', () => ({
Alert: {
alert: jest.fn(),
},
}));

describe('extractURLParams', () => {
const mockUrlParser = UrlParser as jest.MockedClass<typeof UrlParser>;
// const mockUrlParser = UrlParser as jest.MockedClass<typeof UrlParser>;
const mockQs = qs as jest.Mocked<typeof qs>;

beforeEach(() => {
jest.clearAllMocks();
});
it('should correctly extract parameters from a valid URL with query parameters', () => {

it('extracts parameters from a valid URL with query parameters', () => {
const url = `${PROTOCOLS.DAPP}/https://example.com?uri=test&redirect=true&channelId=123&comm=test&pubkey=abc&v=2`;
const expectedParams = {
uri: 'test',
Expand All @@ -41,18 +32,42 @@ describe('extractURLParams', () => {
sdkVersion: '',
channelId: '123',
comm: 'test',
pubkey: 'abc',
v: '2',
attributionId: '',
utm: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
};

mockUrlParser.mockImplementation(
() =>
({
query:
'?uri=test&redirect=true&channelId=123&comm=test&pubkey=abc&v=2',
} as unknown as UrlParser<string>),
);
mockQs.parse.mockReturnValue(expectedParams);

const { params } = extractURLParams(url);

expect(params).toEqual(expectedParams);
});

it('extracts UTM parameters from a URL', () => {
const url = `${PROTOCOLS.DAPP}/https://example.com?utm_source=facebook&utm_medium=social&utm_campaign=summer_sale&utm_term=wallet&utm_content=banner`;
const expectedParams = {
uri: '',
redirect: '',
originatorInfo: '',
rpc: '',
sdkVersion: '',
channelId: '',
comm: '',
v: '',
pubkey: '',
attributionId: '',
utm_source: 'facebook',
utm_medium: 'social',
utm_campaign: 'summer_sale',
utm_term: 'wallet',
utm_content: 'banner',
};

mockQs.parse.mockReturnValue(expectedParams);

Expand All @@ -61,16 +76,9 @@ describe('extractURLParams', () => {
expect(params).toEqual(expectedParams);
});

it('should return an empty params object when the URL has no query parameters', () => {
it('returns an empty params object when the URL has no query parameters', () => {
const url = `${PROTOCOLS.DAPP}/https://example.com`;

mockUrlParser.mockImplementation(
() =>
({
query: '',
} as unknown as UrlParser<string>),
);

const { params } = extractURLParams(url);

expect(params).toEqual({
Expand All @@ -84,21 +92,18 @@ describe('extractURLParams', () => {
pubkey: '',
v: '',
attributionId: '',
utm: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
});
});

it('should handle invalid query parameters and show an alert when parsing fails', () => {
it('handles invalid query parameters and shows an alert when parsing fails', () => {
const url = `${PROTOCOLS.DAPP}/https://example.com?invalid=param`;
const errorMessage = 'Invalid query parameter';

mockUrlParser.mockImplementation(
() =>
({
query: '?invalid=param',
} as unknown as UrlParser<string>),
);

mockQs.parse.mockImplementation(() => {
throw new Error(errorMessage);
});
Expand All @@ -118,7 +123,11 @@ describe('extractURLParams', () => {
pubkey: '',
v: '',
attributionId: '',
utm: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
});

expect(alertSpy).toHaveBeenCalledWith(
Expand All @@ -127,7 +136,7 @@ describe('extractURLParams', () => {
);
});

it('should correctly parse and extract parameters from a URL with valid query parameters', () => {
it('parses and extracts parameters from a URL with valid query parameters', () => {
const url = `${PROTOCOLS.DAPP}/https://example.com?uri=test&redirect=false&channelId=456&comm=other&pubkey=xyz`;
const expectedParams = {
uri: 'test',
Expand All @@ -140,15 +149,40 @@ describe('extractURLParams', () => {
sdkVersion: '',
pubkey: 'xyz',
attributionId: '',
utm: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
};

mockUrlParser.mockImplementation(
() =>
({
query: '?uri=test&redirect=false&channelId=456&comm=other&pubkey=xyz',
} as unknown as UrlParser<string>),
);
mockQs.parse.mockReturnValue(expectedParams);

const { params } = extractURLParams(url);

expect(params).toEqual(expectedParams);
});

it('extracts parameters from a valid URL with duplicate query parameters', () => {
// pubkey and comm is duplicated
const url = `${PROTOCOLS.DAPP}/https://example.com?uri=test&redirect=true&channelId=123&comm=test&comm=test&pubkey=abc&v=2&pubkey=abc`;
const expectedParams = {
uri: 'test',
redirect: 'true',
originatorInfo: '',
rpc: '',
sdkVersion: '',
channelId: '123',
comm: 'test',
pubkey: 'abc',
v: '2',
attributionId: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
};

mockQs.parse.mockReturnValue(expectedParams);

Expand Down
26 changes: 15 additions & 11 deletions app/core/DeeplinkManager/ParseManager/extractURLParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Alert } from 'react-native';
import UrlParser from 'url-parse';
import { strings } from '../../../../locales/i18n';
import { PROTOCOLS } from '../../../constants/deeplinks';
import Logger from '../../../util/Logger';
import DevLogger from '../../SDKConnect/utils/DevLogger';

export interface DeeplinkUrlParams {
uri: string;
Expand All @@ -20,7 +18,11 @@ export interface DeeplinkUrlParams {
originatorInfo?: string;
request?: string;
attributionId?: string;
utm?: string;
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;
utm_term?: string;
utm_content?: string;
account?: string; // This is the format => "address@chainId"
}

Expand All @@ -42,21 +44,23 @@ function extractURLParams(url: string) {
channelId: '',
comm: '',
attributionId: '',
utm: '',
utm_source: '',
utm_medium: '',
utm_campaign: '',
utm_term: '',
utm_content: '',
};

DevLogger.log(`extractParams:: urlObj`, urlObj);

if (urlObj.query.length) {
try {
params = qs.parse(
urlObj.query.substring(1),
) as unknown as DeeplinkUrlParams;
// Use arrayLimit: 1 to prevent arrays from being returned for duplicate parameters
const parsedParams = qs.parse(urlObj.query.substring(1), {
arrayLimit: 99,
});
params = { ...params, ...parsedParams };

if (params.message) {
Logger.log('extractParams:: message before...: ', params.message);
params.message = params.message?.replace(/ /g, '+');
Logger.log('extractParams:: message after: ', params.message);
}
} catch (e) {
if (e) Alert.alert(strings('deeplink.invalid'), e.toString());
Expand Down
Loading
Loading