diff --git a/.eslintignore b/.eslintignore
index df977782c..80f916491 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -13,4 +13,5 @@ CHANGELOG.md
wdio
/app/util/test/testSetup.js
/app/lib/ppom/ppom.html.js
+/app/lib/ppom/blockaid-version.js
/ppom
diff --git a/.prettierignore b/.prettierignore
index 818a1d22c..55e3423c3 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -17,4 +17,5 @@ scripts
locales
.storybook
/ppom
-app/lib/ppom/ppom.html.js
\ No newline at end of file
+app/lib/ppom/ppom.html.js
+/app/lib/ppom/blockaid-version.js
\ No newline at end of file
diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx b/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx
index 56c2c89e0..8db252091 100644
--- a/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx
+++ b/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx
@@ -17,6 +17,10 @@ jest.mock('../../../util/blockaid', () => ({
isBlockaidFeatureEnabled: jest.fn().mockReturnValue(true),
}));
+jest.mock('react-native-gzip', () => ({
+ deflate: (val: any) => val,
+}));
+
const mockState = {
engine: {
backgroundState: {
@@ -26,22 +30,31 @@ const mockState = {
},
};
-describe('BlockaidBanner', () => {
- const mockFeatures = [
- 'We found attack vectors in this request',
- 'This request shows a fake token name and icon.',
- 'If you approve this request, a third party known for scams might take all your assets.',
- 'Operator is an EOA',
- 'Operator is untrusted according to previous activity',
- ];
+const mockFeatures = [
+ 'We found attack vectors in this request',
+ 'This request shows a fake token name and icon.',
+ 'If you approve this request, a third party known for scams might take all your assets.',
+ 'Operator is an EOA',
+ 'Operator is untrusted according to previous activity',
+];
+
+const securityAlertResponse = {
+ result_type: ResultType.Failed,
+ reason: Reason.failed,
+ features: mockFeatures,
+ block: 123,
+ req: {},
+ chainId: '0x1',
+};
+describe('BlockaidBanner', () => {
it('should render correctly', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -54,9 +67,9 @@ describe('BlockaidBanner', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -78,9 +91,9 @@ describe('BlockaidBanner', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -93,9 +106,9 @@ describe('BlockaidBanner', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -133,9 +146,9 @@ describe('BlockaidBanner', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -219,9 +232,9 @@ describe('BlockaidBanner', () => {
const wrapper = renderWithProvider(
,
{ state: mockState },
@@ -234,13 +247,7 @@ describe('BlockaidBanner', () => {
it('should render normal banner alert if resultType is failed', async () => {
const wrapper = renderWithProvider(
- ,
+ ,
{ state: mockState },
);
diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.tsx b/app/components/UI/BlockaidBanner/BlockaidBanner.tsx
index d8807110d..7b8f9cb17 100644
--- a/app/components/UI/BlockaidBanner/BlockaidBanner.tsx
+++ b/app/components/UI/BlockaidBanner/BlockaidBanner.tsx
@@ -2,8 +2,8 @@ import React, { useEffect, useState } from 'react';
import { ActivityIndicator } from 'react-native';
import { useSelector } from 'react-redux';
import { View } from 'react-native-animatable';
-
import { captureException } from '@sentry/react-native';
+import { deflate } from 'react-native-gzip';
import { strings } from '../../../../locales/i18n';
import { AccordionHeaderHorizontalAlignment } from '../../../component-library/components/Accordions/Accordion';
@@ -20,6 +20,7 @@ import Icon from '../../../component-library/components/Icons/Icon/Icon';
import Text from '../../../component-library/components/Texts/Text/Text';
import { useStyles } from '../../../component-library/hooks/useStyles';
import { isBlockaidFeatureEnabled } from '../../../util/blockaid';
+import { NETWORKS_CHAIN_ID } from '../../../constants/network';
import {
ATTRIBUTION_LINE_TEST_ID,
FALSE_POSITIVE_REPOST_LINE_TEST_ID,
@@ -35,11 +36,26 @@ import {
import BlockaidBannerLink from './BlockaidBannerLink';
import {
BLOCKAID_ATTRIBUTION_LINK,
- BLOCKAID_SUPPORT_LINK,
+ FALSE_POSITIVE_REPORT_BASE_URL,
+ UTM_SOURCE,
} from '../../../constants/urls';
import { isMainnetByChainId } from '../../../util/networks';
-import { selectChainId } from '../../../selectors/networkController';
import { selectIsSecurityAlertsEnabled } from '../../../selectors/preferencesController';
+import BlockaidVersionInfo from '../../../lib/ppom/blockaid-version';
+
+const BLOCKAID_SUPPORTED_NETWORK_NAMES = {
+ [NETWORKS_CHAIN_ID.MAINNET]: 'Ethereum Mainnet',
+ [NETWORKS_CHAIN_ID.BSC]: 'Binance Smart Chain',
+ [NETWORKS_CHAIN_ID.OPTIMISM]: 'Optimism',
+ [NETWORKS_CHAIN_ID.POLYGON]: 'Polygon',
+ [NETWORKS_CHAIN_ID.ARBITRUM]: 'Arbitrum',
+ [NETWORKS_CHAIN_ID.LINEA_MAINNET]: 'Linea',
+};
+
+const getReportUrl = (encodedData: string) =>
+ `${FALSE_POSITIVE_REPORT_BASE_URL}?data=${encodeURIComponent(
+ encodedData.toString(),
+ )}&utm_source=${UTM_SOURCE}`;
const getTitle = (reason: Reason): string =>
strings(
@@ -89,7 +105,7 @@ const BlockaidBanner = (bannerProps: BlockaidBannerProps) => {
} = bannerProps;
const { styles, theme } = useStyles(styleSheet, { style });
const [displayPositiveResponse, setDisplayPositiveResponse] = useState(false);
- const chainId = useSelector(selectChainId);
+ const [reportUrl, setReportUrl] = useState('');
const isSecurityAlertsEnabled = useSelector(selectIsSecurityAlertsEnabled);
useEffect(() => {
@@ -98,16 +114,48 @@ const BlockaidBanner = (bannerProps: BlockaidBannerProps) => {
}
}, [securityAlertResponse]);
+ useEffect(() => {
+ if (!securityAlertResponse) {
+ return;
+ }
+ const { result_type, reason, features, block, req, chainId } =
+ securityAlertResponse;
+
+ if (!req || !chainId) {
+ return;
+ }
+
+ const reportData = {
+ domain: req.origin,
+ jsonRpcMethod: req.method,
+ jsonRpcParams: JSON.stringify(req.params),
+ blockNumber: block,
+ chain: BLOCKAID_SUPPORTED_NETWORK_NAMES[chainId],
+ classification: reason,
+ resultType: result_type,
+ reproduce: JSON.stringify(features),
+ blockaidVersion: BlockaidVersionInfo.BlockaidVersion,
+ };
+
+ (async () => {
+ const compressed = await deflate(JSON.stringify(reportData));
+ setReportUrl(getReportUrl(compressed));
+ })();
+ }, [securityAlertResponse]);
+
if (
!securityAlertResponse ||
!isBlockaidFeatureEnabled() ||
- !isMainnetByChainId(chainId) ||
!isSecurityAlertsEnabled
) {
return null;
}
- const { result_type, reason, features } = securityAlertResponse;
+ const { result_type, reason, features, chainId } = securityAlertResponse;
+
+ if (!isMainnetByChainId(chainId)) {
+ return null;
+ }
if (securityAlertResponse.reason === Reason.requestInProgress) {
return (
@@ -192,8 +240,8 @@ const BlockaidBanner = (bannerProps: BlockaidBannerProps) => {
diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.types.ts b/app/components/UI/BlockaidBanner/BlockaidBanner.types.ts
index 516a72d80..e6e9943b0 100644
--- a/app/components/UI/BlockaidBanner/BlockaidBanner.types.ts
+++ b/app/components/UI/BlockaidBanner/BlockaidBanner.types.ts
@@ -35,6 +35,9 @@ export interface SecurityAlertResponse {
features?: (string | Record)[];
result_type: ResultType;
providerRequestsCount?: Record;
+ block?: number;
+ chainId?: string;
+ req?: Record;
}
type BlockaidBannerAllProps = BannerAlertProps & {
diff --git a/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap b/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap
index 3e8439763..ceb83088c 100644
--- a/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap
+++ b/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap
@@ -12,6 +12,8 @@ exports[`BlockaidBanner should render correctly 1`] = `
({
isBlockaidFeatureEnabled: jest.fn().mockReturnValue(true),
}));
+jest.mock('react-native-gzip', () => ({
+ deflate: (val: any) => val,
+}));
+
const mockState = {
engine: {
backgroundState: {
@@ -24,6 +28,9 @@ const mockState = {
response: {
result_type: ResultType.Warning,
reason: Reason.approvalFarming,
+ block: 123,
+ req: {},
+ chainId: '0x1',
},
},
},
@@ -60,6 +67,9 @@ describe('TransactionBlockaidBanner', () => {
response: {
result_type: ResultType.Warning,
reason: Reason.approvalFarming,
+ block: 123,
+ req: {},
+ chainId: '0x1',
},
},
},
diff --git a/app/components/UI/TransactionBlockaidBanner/__snapshots__/TransactionBlockaidBanner.test.tsx.snap b/app/components/UI/TransactionBlockaidBanner/__snapshots__/TransactionBlockaidBanner.test.tsx.snap
index e6505700d..594c30b2b 100644
--- a/app/components/UI/TransactionBlockaidBanner/__snapshots__/TransactionBlockaidBanner.test.tsx.snap
+++ b/app/components/UI/TransactionBlockaidBanner/__snapshots__/TransactionBlockaidBanner.test.tsx.snap
@@ -8,7 +8,10 @@ exports[`TransactionBlockaidBanner should render correctly 1`] = `
{
};
});
+jest.mock('react-native-gzip', () => ({
+ deflate: (val: any) => val,
+}));
+
const mockState = {
engine: {
backgroundState: {
@@ -124,6 +128,9 @@ jest.mock('react-redux', () => {
result_type: 'Malicious',
reason: 'blur_farming',
providerRequestsCount: {},
+ block: 123,
+ req: {},
+ chainId: '0x1',
};
return {
...jest.requireActual('react-redux'),
@@ -171,6 +178,9 @@ describe('TransactionReview', () => {
result_type: 'Malicious',
reason: 'blur_farming',
providerRequestsCount: {},
+ block: 123,
+ req: {},
+ chainId: '0x1',
};
const trackEventSypy = jest
.spyOn(analyticsV2, 'trackEvent')
@@ -222,9 +232,9 @@ describe('TransactionReview', () => {
await queryByTestId(FALSE_POSITIVE_REPOST_LINE_TEST_ID),
).toBeDefined();
expect(await queryByText('Something doesn’t look right?')).toBeDefined();
- expect(await queryByText('Contact Us')).toBeDefined();
+ expect(await queryByText('Report an issue')).toBeDefined();
- fireEvent.press(await getByText('Contact Us'));
+ fireEvent.press(await getByText('Report an issue'));
expect(trackEventSypy).toHaveBeenCalledTimes(1);
expect(blockaidMetricsParamsSpy).toHaveBeenCalledTimes(1);
@@ -234,6 +244,9 @@ describe('TransactionReview', () => {
providerRequestsCount: {},
reason: 'blur_farming',
result_type: 'Malicious',
+ block: 123,
+ req: {},
+ chainId: '0x1',
},
});
});
diff --git a/app/constants/urls.ts b/app/constants/urls.ts
index b5f353d2e..ed8e13d91 100644
--- a/app/constants/urls.ts
+++ b/app/constants/urls.ts
@@ -61,7 +61,9 @@ export const MM_PLAY_STORE_LINK = `market://details?id=${AppConstants.BUNDLE_IDS
export const MM_SDK_DEEPLINK = `https://${AppConstants.MM_UNIVERSAL_LINK_HOST}/connect?`;
export const BLOCKAID_ATTRIBUTION_LINK = 'https://blockaid.io';
-export const BLOCKAID_SUPPORT_LINK = 'https://support.metamask.io/hc/en-us';
+export const FALSE_POSITIVE_REPORT_BASE_URL =
+ 'https://blockaid-false-positive-portal.metamask.io';
+export const UTM_SOURCE = 'metamask-ppom';
export const SEPOLIA_FAUCET = 'https://www.infura.io/faucet/sepolia';
export const LINEA_FAUCET = 'https://www.infura.io/faucet/linea';
diff --git a/app/lib/ppom/PPOMView.tsx b/app/lib/ppom/PPOMView.tsx
index 108fb23fa..36657e985 100644
--- a/app/lib/ppom/PPOMView.tsx
+++ b/app/lib/ppom/PPOMView.tsx
@@ -1,7 +1,7 @@
-import createInvoke from 'react-native-webview-invoke/native';
import React, { Component, RefObject } from 'react';
-import { View, StyleSheet } from 'react-native';
+import { StyleSheet, View } from 'react-native';
import { WebView } from 'react-native-webview';
+import createInvoke from 'react-native-webview-invoke/native';
import Logger from '../../util/Logger';
import asyncInvoke from './invoke-lib';
diff --git a/app/lib/ppom/array-buffer.test.ts b/app/lib/ppom/array-buffer.test.ts
index 927a352cf..c0e5270e1 100644
--- a/app/lib/ppom/array-buffer.test.ts
+++ b/app/lib/ppom/array-buffer.test.ts
@@ -1,4 +1,4 @@
-import { base64toArrayBuffer, arrayBufferToBase64 } from './array-buffer';
+import { arrayBufferToBase64, base64toArrayBuffer } from './array-buffer';
describe('ArrayBuffer', () => {
it('should correclly inter-convert string to arrayBuffer', () => {
diff --git a/app/lib/ppom/blockaid-version.js b/app/lib/ppom/blockaid-version.js
new file mode 100644
index 000000000..e3cb39a43
--- /dev/null
+++ b/app/lib/ppom/blockaid-version.js
@@ -0,0 +1 @@
+var e={d:(o,r)=>{for(var t in r)e.o(r,t)&&!e.o(o,t)&&Object.defineProperty(o,t,{enumerable:!0,get:r[t]})},o:(e,o)=>Object.prototype.hasOwnProperty.call(e,o)},o={};e.d(o,{Z:()=>r});const r={BlockaidVersion:"1.4.0"};var t=o.Z;export{t as default};
\ No newline at end of file
diff --git a/app/lib/ppom/ppom-util.test.ts b/app/lib/ppom/ppom-util.test.ts
index 57b1da7fc..fe48136f8 100644
--- a/app/lib/ppom/ppom-util.test.ts
+++ b/app/lib/ppom/ppom-util.test.ts
@@ -1,7 +1,7 @@
-import PPOMUtil from './ppom-util';
-import Engine from '../../core/Engine';
-import * as TransactionActions from '../../actions/transaction'; // eslint-disable-line import/no-namespace
import * as SignatureRequestActions from '../../actions/signatureRequest'; // eslint-disable-line import/no-namespace
+import * as TransactionActions from '../../actions/transaction'; // eslint-disable-line import/no-namespace
+import Engine from '../../core/Engine';
+import PPOMUtil from './ppom-util';
jest.mock('../../core/Engine', () => ({
context: {
diff --git a/app/lib/ppom/ppom-util.ts b/app/lib/ppom/ppom-util.ts
index 161fa269f..1e3d48052 100644
--- a/app/lib/ppom/ppom-util.ts
+++ b/app/lib/ppom/ppom-util.ts
@@ -1,14 +1,14 @@
-import Logger from '../../util/Logger';
-import Engine from '../../core/Engine';
-import { isBlockaidFeatureEnabled } from '../../util/blockaid';
-import { isMainnetByChainId } from '../../util/networks';
+import setSignatureRequestSecurityAlertResponse from '../../actions/signatureRequest';
+import { setTransactionSecurityAlertResponse } from '../../actions/transaction';
import {
Reason,
ResultType,
} from '../../components/UI/BlockaidBanner/BlockaidBanner.types';
+import Engine from '../../core/Engine';
import { store } from '../../store';
-import setSignatureRequestSecurityAlertResponse from '../../actions/signatureRequest';
-import { setTransactionSecurityAlertResponse } from '../../actions/transaction';
+import { isBlockaidFeatureEnabled } from '../../util/blockaid';
+import Logger from '../../util/Logger';
+import { isMainnetByChainId } from '../../util/networks';
const ConfirmationMethods = Object.freeze([
'eth_sendRawTransaction',
@@ -73,6 +73,11 @@ const validateRequest = async (req: any, transactionId?: string) => {
securityAlertResponse = await ppomController.usePPOM((ppom: any) =>
ppom.validateJsonRpc(req),
);
+ securityAlertResponse = {
+ ...securityAlertResponse,
+ req,
+ chainId: currentChainId,
+ };
}
} catch (e) {
Logger.log(`Error validating JSON RPC using PPOM: ${e}`);
diff --git a/app/lib/ppom/rnfs-storage-backend.ts b/app/lib/ppom/rnfs-storage-backend.ts
index bf3a96c58..ea5bae9e4 100644
--- a/app/lib/ppom/rnfs-storage-backend.ts
+++ b/app/lib/ppom/rnfs-storage-backend.ts
@@ -1,5 +1,5 @@
-import RNFS from 'react-native-fs';
import CryptoJS, { SHA256 } from 'crypto-js';
+import RNFS from 'react-native-fs';
import { StorageBackend, StorageKey } from '@metamask/ppom-validator';
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 0432d7c6a..eef24418f 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -1,4 +1,5 @@
PODS:
+ - Base64 (1.1.2)
- boost (1.76.0)
- Branch (1.43.2)
- BVLinearGradient (2.5.6):
@@ -76,6 +77,7 @@ PODS:
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
+ - GZIP (1.3.1)
- GzipSwift (5.1.1)
- libevent (2.1.12)
- lottie-ios (3.4.1)
@@ -341,6 +343,10 @@ PODS:
- React-Core
- react-native-get-random-values (1.8.0):
- React-Core
+ - react-native-gzip (1.1.0):
+ - Base64
+ - GZIP
+ - React-Core
- react-native-in-app-review (3.2.3):
- React
- react-native-launch-arguments (4.0.1):
@@ -599,6 +605,7 @@ DEPENDENCIES:
- react-native-camera (from `../node_modules/react-native-camera`)
- "react-native-cookies (from `../node_modules/@react-native-cookies/cookies`)"
- react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
+ - react-native-gzip (from `../node_modules/react-native-gzip`)
- react-native-in-app-review (from `../node_modules/react-native-in-app-review`)
- react-native-launch-arguments (from `../node_modules/react-native-launch-arguments`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
@@ -654,6 +661,7 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
+ - Base64
- Branch
- CocoaAsyncSocket
- Flipper
@@ -666,6 +674,7 @@ SPEC REPOS:
- Flipper-RSocket
- FlipperKit
- fmt
+ - GZIP
- GzipSwift
- libevent
- OpenSSL-Universal
@@ -737,6 +746,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-cookies/cookies"
react-native-get-random-values:
:path: "../node_modules/react-native-get-random-values"
+ react-native-gzip:
+ :path: "../node_modules/react-native-gzip"
react-native-in-app-review:
:path: "../node_modules/react-native-in-app-review"
react-native-launch-arguments:
@@ -843,6 +854,7 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
+ Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
boost: 57d2868c099736d80fcd648bf211b4431e51a558
Branch: 4ac024cb3c29b0ef628048694db3c4cfa679beb0
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
@@ -861,6 +873,7 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
+ GZIP: e6922ed5bdd1d77d84589d50821ac34ea0c38d4b
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
lottie-ios: 016449b5d8be0c3dcbcfa0a9988469999cd04c5d
@@ -889,6 +902,7 @@ SPEC CHECKSUMS:
react-native-camera: b8cc03e2feec0c04403d0998e37cf519d8fd4c6f
react-native-cookies: f54fcded06bb0cda05c11d86788020b43528a26c
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
+ react-native-gzip: c5e87ee9e359f02350e3a2ee52eb35eddc398868
react-native-in-app-review: 23f4f5b9fcd94339dd5d93c6230557f9c67c7dda
react-native-launch-arguments: 4e0fd58e56dcc7f52eedef9dc8eff81eb73ced7a
react-native-netinfo: e849fc21ca2f4128a5726c801a82fc6f4a6db50d
diff --git a/jest.config.js b/jest.config.js
index ee231e18c..bd6ac3f3e 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -22,6 +22,7 @@ const config = {
'/app/util/test/',
'/app/util/testUtils/',
'/app/lib/ppom/ppom.html.js',
+ '/app/lib/ppom/blockaid-version.js',
],
coverageReporters: ['text-summary', 'lcov'],
coverageDirectory: '/tests/coverage',
diff --git a/locales/languages/en.json b/locales/languages/en.json
index dc39f096f..e85d97e27 100644
--- a/locales/languages/en.json
+++ b/locales/languages/en.json
@@ -15,6 +15,7 @@
"seaport_farming_description": "If you approve this request, someone can steal your assets listed on OpenSea.",
"see_details": "See details",
"does_not_look_right": "Something doesn’t look right?",
+ "report_an_issue": "Report an issue",
"suspicious_request_title": "This is a suspicious request",
"trade_order_farming_description": "If you approve this request, you might lose your assets.",
"transfer_farming_description": "If you approve this request, a third party known for scams will take all your assets.",
diff --git a/package.json b/package.json
index 3a15fd3f9..6a126fb37 100644
--- a/package.json
+++ b/package.json
@@ -308,6 +308,7 @@
"react-native-fs": "^2.16.6",
"react-native-gesture-handler": "^1.10.3",
"react-native-get-random-values": "^1.8.0",
+ "react-native-gzip": "^1.1.0",
"react-native-i18n": "2.0.15",
"react-native-in-app-review": "^3.2.3",
"react-native-inappbrowser-reborn": "^3.7.0",
diff --git a/ppom/.eslintignore b/ppom/.eslintignore
index d8c4ab6d1..6c8eb8ee9 100644
--- a/ppom/.eslintignore
+++ b/ppom/.eslintignore
@@ -1,2 +1,3 @@
/webpack.config.html-js.js
-/webpack.config.html.js
\ No newline at end of file
+/webpack.config.html.js
+/webpack.config.version.js
\ No newline at end of file
diff --git a/ppom/package.json b/ppom/package.json
index 0d2080380..6f7d362a0 100644
--- a/ppom/package.json
+++ b/ppom/package.json
@@ -20,7 +20,8 @@
"lint": "eslint '**/*.{js,ts,tsx}'",
"build-html": "webpack --mode production --config ./webpack.config.html.js",
"build-html-js": "webpack --mode production --config ./webpack.config.html-js.js",
- "build": "yarn clean && yarn build-html && yarn build-html-js",
+ "build-version": "webpack --mode production --config ./webpack.config.version.js",
+ "build": "yarn clean && yarn build-html && yarn build-html-js && yarn build-version",
"clean": "rm -rf ../app/lib/ppom/ppom.html.js && rm -rf ./dist"
}
}
diff --git a/ppom/src/blockaid-version.js b/ppom/src/blockaid-version.js
new file mode 100644
index 000000000..d46b37d3a
--- /dev/null
+++ b/ppom/src/blockaid-version.js
@@ -0,0 +1,3 @@
+import BlockaidPackage from '@blockaid/ppom_release/package.json';
+
+export default { BlockaidVersion: BlockaidPackage.version };
diff --git a/ppom/webpack.config.version.js b/ppom/webpack.config.version.js
new file mode 100644
index 000000000..f68f7e012
--- /dev/null
+++ b/ppom/webpack.config.version.js
@@ -0,0 +1,13 @@
+const path = require('path');
+
+module.exports = {
+ entry: './src/blockaid-version.js',
+ output: {
+ path: path.resolve(__dirname, '../app/lib/ppom'),
+ filename: 'blockaid-version.js',
+ library: {
+ type: 'module',
+ },
+ },
+ experiments: { outputModule: true },
+};
diff --git a/yarn.lock b/yarn.lock
index 09eb86a28..8c9771920 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2360,11 +2360,11 @@
strip-ansi "^6.0.0"
"@jest/create-cache-key-function@^29.2.1":
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.6.1.tgz#eb69da959e78e8457757451166b4b0f7b64fe679"
- integrity sha512-d77/1BbNLbJDBV6tH7ctYpau+3tnU5YMhg36uGabW4VDrl1Arp6E0jDRioHFoFqIbm+BXMVbyQc9MpfKo6OIQQ==
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz#793be38148fab78e65f40ae30c36785f4ad859f0"
+ integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==
dependencies:
- "@jest/types" "^29.6.1"
+ "@jest/types" "^29.6.3"
"@jest/environment@^28.1.3":
version "28.1.3"
@@ -2376,15 +2376,15 @@
"@types/node" "*"
jest-mock "^28.1.3"
-"@jest/environment@^29.6.1":
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.1.tgz#ee358fff2f68168394b4a50f18c68278a21fe82f"
- integrity sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==
+"@jest/environment@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7"
+ integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==
dependencies:
- "@jest/fake-timers" "^29.6.1"
- "@jest/types" "^29.6.1"
+ "@jest/fake-timers" "^29.7.0"
+ "@jest/types" "^29.6.3"
"@types/node" "*"
- jest-mock "^29.6.1"
+ jest-mock "^29.7.0"
"@jest/expect-utils@^28.1.3":
version "28.1.3"
@@ -2413,17 +2413,17 @@
jest-mock "^28.1.3"
jest-util "^28.1.3"
-"@jest/fake-timers@^29.6.1":
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.1.tgz#c773efddbc61e1d2efcccac008139f621de57c69"
- integrity sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==
+"@jest/fake-timers@^29.7.0":
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565"
+ integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==
dependencies:
- "@jest/types" "^29.6.1"
+ "@jest/types" "^29.6.3"
"@sinonjs/fake-timers" "^10.0.2"
"@types/node" "*"
- jest-message-util "^29.6.1"
- jest-mock "^29.6.1"
- jest-util "^29.6.1"
+ jest-message-util "^29.7.0"
+ jest-mock "^29.7.0"
+ jest-util "^29.7.0"
"@jest/globals@^28.1.3":
version "28.1.3"
@@ -2472,10 +2472,10 @@
dependencies:
"@sinclair/typebox" "^0.24.1"
-"@jest/schemas@^29.6.0":
- version "29.6.0"
- resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040"
- integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==
+"@jest/schemas@^29.6.3":
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03"
+ integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==
dependencies:
"@sinclair/typebox" "^0.27.8"
@@ -2563,12 +2563,12 @@
"@types/yargs" "^17.0.8"
chalk "^4.0.0"
-"@jest/types@^29.6.1":
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2"
- integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==
+"@jest/types@^29.6.3":
+ version "29.6.3"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59"
+ integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==
dependencies:
- "@jest/schemas" "^29.6.0"
+ "@jest/schemas" "^29.6.3"
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^3.0.0"
"@types/node" "*"
@@ -5022,7 +5022,7 @@
resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e"
integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ==
-"@react-native/normalize-color@*", "@react-native/normalize-color@2.1.0":
+"@react-native/normalize-color@*", "@react-native/normalize-color@2.1.0", "@react-native/normalize-color@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91"
integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA==
@@ -12673,13 +12673,13 @@ deprecated-react-native-prop-types@^2.2.0:
prop-types "*"
deprecated-react-native-prop-types@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz#a275f84cd8519cd1665e8df3c99e9067d57a23ec"
- integrity sha512-J0jCJcsk4hMlIb7xwOZKLfMpuJn6l8UtrPEzzQV5ewz5gvKNYakhBuq9h2rWX7YwHHJZFhU5W8ye7dB9oN8VcQ==
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.2.tgz#e724a9837e6a7ccb778753c06ae4f79065873493"
+ integrity sha512-JoZY5iNM+oJlN2Ldpq0KSi0h3Nig4hlNJj5nWzWp8eL3uikMCvHwjSGPitwkEw0arL5JFra5nuGJQpXRbEjApg==
dependencies:
- "@react-native/normalize-color" "*"
- invariant "*"
- prop-types "*"
+ "@react-native/normalize-color" "^2.1.0"
+ invariant "^2.2.4"
+ prop-types "^15.8.1"
deprecation@^2.0.0, deprecation@^2.3.1:
version "2.3.1"
@@ -13315,9 +13315,9 @@ env-paths@^2.2.0:
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
envinfo@^7.7.2, envinfo@^7.7.3:
- version "7.10.0"
- resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13"
- integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==
+ version "7.11.0"
+ resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f"
+ integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==
enzyme-adapter-react-16@1.10.0:
version "1.10.0"
@@ -17333,16 +17333,16 @@ jest-environment-node@^28.1.3:
jest-util "^28.1.3"
jest-environment-node@^29.2.1:
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.1.tgz#08a122dece39e58bc388da815a2166c58b4abec6"
- integrity sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376"
+ integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==
dependencies:
- "@jest/environment" "^29.6.1"
- "@jest/fake-timers" "^29.6.1"
- "@jest/types" "^29.6.1"
+ "@jest/environment" "^29.7.0"
+ "@jest/fake-timers" "^29.7.0"
+ "@jest/types" "^29.6.3"
"@types/node" "*"
- jest-mock "^29.6.1"
- jest-util "^29.6.1"
+ jest-mock "^29.7.0"
+ jest-util "^29.7.0"
jest-get-type@^26.3.0:
version "26.3.0"
@@ -17416,18 +17416,18 @@ jest-message-util@^28.1.3:
slash "^3.0.0"
stack-utils "^2.0.3"
-jest-message-util@^29.6.1:
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.1.tgz#d0b21d87f117e1b9e165e24f245befd2ff34ff8d"
- integrity sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==
+jest-message-util@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3"
+ integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==
dependencies:
"@babel/code-frame" "^7.12.13"
- "@jest/types" "^29.6.1"
+ "@jest/types" "^29.6.3"
"@types/stack-utils" "^2.0.0"
chalk "^4.0.0"
graceful-fs "^4.2.9"
micromatch "^4.0.4"
- pretty-format "^29.6.1"
+ pretty-format "^29.7.0"
slash "^3.0.0"
stack-utils "^2.0.3"
@@ -17439,14 +17439,14 @@ jest-mock@^28.1.3:
"@jest/types" "^28.1.3"
"@types/node" "*"
-jest-mock@^29.6.1:
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.1.tgz#049ee26aea8cbf54c764af649070910607316517"
- integrity sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==
+jest-mock@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347"
+ integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==
dependencies:
- "@jest/types" "^29.6.1"
+ "@jest/types" "^29.6.3"
"@types/node" "*"
- jest-util "^29.6.1"
+ jest-util "^29.7.0"
jest-pnp-resolver@^1.2.2:
version "1.2.2"
@@ -17602,12 +17602,12 @@ jest-util@^28.1.3:
graceful-fs "^4.2.9"
picomatch "^2.2.3"
-jest-util@^29.6.1:
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb"
- integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==
+jest-util@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc"
+ integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==
dependencies:
- "@jest/types" "^29.6.1"
+ "@jest/types" "^29.6.3"
"@types/node" "*"
chalk "^4.0.0"
ci-info "^3.2.0"
@@ -21314,12 +21314,12 @@ pretty-format@^28.0.0, pretty-format@^28.1.3:
ansi-styles "^5.0.0"
react-is "^18.0.0"
-pretty-format@^29.0.0, pretty-format@^29.6.1:
- version "29.6.1"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.1.tgz#ec838c288850b7c4f9090b867c2d4f4edbfb0f3e"
- integrity sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==
+pretty-format@^29.0.0, pretty-format@^29.7.0:
+ version "29.7.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
+ integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==
dependencies:
- "@jest/schemas" "^29.6.0"
+ "@jest/schemas" "^29.6.3"
ansi-styles "^5.0.0"
react-is "^18.0.0"
@@ -21465,7 +21465,7 @@ prop-types-exact@^1.2.0:
object.assign "^4.1.0"
reflect.ownkeys "^0.2.0"
-prop-types@*, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
+prop-types@*, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -22171,6 +22171,11 @@ react-native-gradle-plugin@^0.71.19:
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz#3379e28341fcd189bc1f4691cefc84c1a4d7d232"
integrity sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ==
+react-native-gzip@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/react-native-gzip/-/react-native-gzip-1.1.0.tgz#726396afddc348f60d5acc8bfaed89cc4066bacb"
+ integrity sha512-utgM5GNAIsOoMnQHK135tULfQGeEa40NTyybJ2vH87ay9A6XP4K1AZBBwnIHxtzBS+z0mO3dmql5662q5UUNSg==
+
react-native-i18n@2.0.15:
version "2.0.15"
resolved "https://registry.yarnpkg.com/react-native-i18n/-/react-native-i18n-2.0.15.tgz#09b5a9836116fa7dbd0054c46e2d1014c1ef3c65"