Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Pull @metamask/mobile-provider back into metamask-mobile #7494

Merged
merged 27 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9e1b082
webpack v5 attempt
jiexi Oct 13, 2023
6108f85
Merge branch 'main' into jl/pull-in-mobile-provider
jiexi Oct 13, 2023
5c12ac8
Bump readable-stream. Finally working
jiexi Oct 13, 2023
71c5e45
drop old `obj-multiplex`
jiexi Oct 13, 2023
c01403b
use cat instead of `concat-cli`
jiexi Oct 13, 2023
f082921
drop webpack v4 changes
jiexi Oct 13, 2023
e1e0547
cleanup
jiexi Oct 13, 2023
fde69c6
remove asdf tool versions
jiexi Oct 13, 2023
dbbcef9
Move /app/core/Providers to /js
jiexi Oct 13, 2023
041eece
rename postinstall build step
jiexi Oct 13, 2023
20c7f11
move inpage bridge building logic into separate script
jiexi Oct 13, 2023
cb8c820
Merge branch 'main' into jl/pull-in-mobile-provider
jiexi Oct 17, 2023
7cebf0d
Move inpage bridge scripts to /scripts/inpage-bridge
jiexi Oct 17, 2023
63f2732
Revert .storybook/storybook.requires.js
jiexi Oct 17, 2023
455dfc5
revert storybook requires
jiexi Oct 17, 2023
68eb81a
update podlock
jiexi Oct 17, 2023
e9ae602
Merge branch 'main' into jl/pull-in-mobile-provider
jiexi Oct 17, 2023
93bfd43
Merge branch 'main' into jl/pull-in-mobile-provider
jiexi Oct 17, 2023
abecba4
dedupe
jiexi Oct 17, 2023
a918141
fix depcheck webpack-cli
jiexi Oct 17, 2023
86e8a63
dedupe?
jiexi Oct 17, 2023
eb048bc
dedupe
jiexi Oct 18, 2023
d13e9fe
Merge branch 'main' into jl/pull-in-mobile-provider
jiexi Oct 18, 2023
25b0c75
Merge branch 'main' into jl/pull-in-mobile-provider
Cal-L Oct 18, 2023
500fa82
Merge branch 'main' into jl/pull-in-mobile-provider
Cal-L Oct 18, 2023
0495a85
add set -e to build inpage and postinstall scripts
jiexi Oct 18, 2023
de52d61
make postinstall more strict. fix removing missing file
jiexi Oct 18, 2023
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
1 change: 1 addition & 0 deletions .depcheckrc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# List things here that *are - 'used, that depcheck is wrong about'
ignores:
- '@metamask/oss-attribution-generator'
- 'webpack-cli'

# Note: Everything below this line should be removed after investigation
# TODO: Investigate each dependency to see whether it's used
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/scripts/inpage-bridge
/app/core/InpageBridgeWeb3.js
/app/util/blockies.js
__snapshots__
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ buck-out/
tests

# app-specific
/scripts/inpage-bridge/dist
/android/app/src/main/assets/InpageBridgeWeb3.js
/app/core/InpageBridgeWeb3.js

Expand Down
2 changes: 1 addition & 1 deletion app/util/streams.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable import/no-commonjs */
const Through = require('through2');
const ObjectMultiplex = require('obj-multiplex');
const ObjectMultiplex = require('@metamask/object-multiplex');
jiexi marked this conversation as resolved.
Show resolved Hide resolved
const pump = require('pump');

/**
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@
"metro-config": "^0.71.1",
"multihashes": "0.4.14",
"number-to-bn": "1.7.0",
"obj-multiplex": "1.0.0",
"obs-store": "4.0.3",
"path": "0.12.7",
"pbkdf2": "3.1.2",
Expand Down Expand Up @@ -325,7 +324,7 @@
"react-native-webview": "11.13.0",
"react-native-webview-invoke": "^0.6.2",
"react-redux": "7.2.4",
"readable-stream": "1.0.33",
"readable-stream": "2.3.7",
Cal-L marked this conversation as resolved.
Show resolved Hide resolved
"redux": "4.1.1",
"redux-mock-store": "1.5.4",
"redux-persist": "6.0.0",
Expand All @@ -335,7 +334,7 @@
"reselect": "^4.0.0",
"rn-fetch-blob": "^0.12.0",
"socket.io-client": "^4.5.3",
"stream-browserify": "1.0.0",
"stream-browserify": "3.0.0",
Cal-L marked this conversation as resolved.
Show resolved Hide resolved
"through2": "3.0.1",
"unicode-confusables": "^0.1.1",
"url": "0.11.0",
Expand All @@ -359,7 +358,9 @@
"@metamask/eslint-config": "^9.0.0",
"@metamask/eslint-config-typescript": "^9.0.0",
"@metamask/mobile-provider": "^3.0.0",
"@metamask/object-multiplex": "^1.1.0",
"@metamask/oss-attribution-generator": "^2.0.1",
"@metamask/providers": "^13.0.0",
"@metamask/test-dapp": "^7.1.0",
"@react-native-community/datetimepicker": "^7.5.0",
"@react-native-community/eslint-config": "^2.0.0",
Expand Down Expand Up @@ -468,6 +469,8 @@
"ts-node": "^10.5.0",
"typescript": "~4.8.4",
"wdio-cucumberjs-json-reporter": "^4.4.3",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
jiexi marked this conversation as resolved.
Show resolved Hide resolved
"xml2js": "^0.5.0",
"yarn-deduplicate": "^6.0.2"
},
Expand Down
11 changes: 11 additions & 0 deletions scripts/build-inpage-bridge.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
rm app/core/InpageBridgeWeb3.js
mkdir -p scripts/inpage-bridge/dist && rm -rf scripts/inpage-bridge/dist/*
cd scripts/inpage-bridge/inpage
../../../node_modules/.bin/webpack --config webpack.config.js
cd ..
node content-script/build.js
cat dist/inpage-bundle.js content-script/index.js > dist/index-raw.js
../../node_modules/.bin/webpack --config webpack.config.js
cd ../..
cp scripts/inpage-bridge/dist/index.js app/core/InpageBridgeWeb3.js
1 change: 0 additions & 1 deletion scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ checkParameters(){

prebuild(){
# Import provider
cp node_modules/@metamask/mobile-provider/dist/index.js app/core/InpageBridgeWeb3.js
yarn --ignore-engines build:static-logos

# Load JS specific env variables
Expand Down
14 changes: 14 additions & 0 deletions scripts/inpage-bridge/content-script/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const fs = require('fs');
const path = require('path');

const distPath = path.join(__dirname, '..', '/', 'dist');

const inpageContent = fs
.readFileSync(path.join(distPath, 'inpage-content.js'))
.toString();

// wrap the inpage content in a variable declaration
const code = `const inpageBundle = ${JSON.stringify(inpageContent)}`;

fs.writeFileSync(path.join(distPath, 'inpage-bundle.js'), code, 'ascii');
console.log('content-script.js generated succesfully');
147 changes: 147 additions & 0 deletions scripts/inpage-bridge/content-script/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* global inpageBundle */

if (shouldInject()) {
injectScript(inpageBundle);
start();
}

// Functions

/**
* Sets up the stream communication and submits site metadata
*
*/
async function start() {
await domIsReady();
window._metamaskSetupProvider();
}

/**
* Injects a script tag into the current document
*
* @param {string} content - Code to be executed in the current document
*/
function injectScript(content) {
try {
const container = document.head || document.documentElement;

// synchronously execute script in page context
const scriptTag = document.createElement('script');
scriptTag.setAttribute('async', false);
scriptTag.textContent = content;
container.insertBefore(scriptTag, container.children[0]);

// script executed; remove script element from DOM
container.removeChild(scriptTag);
} catch (err) {
console.error('MetaMask script injection failed', err);
}
}

/**
* Determines if the provider should be injected.
*
* @returns {boolean} {@code true} if the provider should be injected.
*/
function shouldInject() {
return (
doctypeCheck() &&
suffixCheck() &&
documentElementCheck() &&
!blockedDomainCheck()
);
}

/**
* Checks the doctype of the current document if it exists
*
* @returns {boolean} {@code true} if the doctype is html or if none exists
*/
function doctypeCheck() {
const { doctype } = window.document;
if (doctype) {
return doctype.name === 'html';
}
return true;
}

/**
* Returns whether or not the extension (suffix) of the current document is
* prohibited.
*
* This checks {@code window.location.pathname} against a set of file extensions
* that should not have the provider injected into them. This check is indifferent
* of query parameters in the location.
*
* @returns {boolean} whether or not the extension of the current document is prohibited
*/
function suffixCheck() {
const prohibitedTypes = [/\\.xml$/u, /\\.pdf$/u];
const currentUrl = window.location.pathname;
for (let i = 0; i < prohibitedTypes.length; i++) {
if (prohibitedTypes[i].test(currentUrl)) {
return false;
}
}
return true;
}

/**
* Checks the documentElement of the current document
*
* @returns {boolean} {@code true} if the documentElement is an html node or if none exists
*/
function documentElementCheck() {
const documentElement = document.documentElement.nodeName;
if (documentElement) {
return documentElement.toLowerCase() === 'html';
}
return true;
}

/**
* Checks if the current domain is blocked
*
* @returns {boolean} {@code true} if the current domain is blocked
*/
function blockedDomainCheck() {
const blockedDomains = [
'uscourts.gov',
'dropbox.com',
'webbyawards.com',
'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
'adyen.com',
'gravityforms.com',
'harbourair.com',
'ani.gamer.com.tw',
'blueskybooking.com',
'sharefile.com',
];
const currentUrl = window.location.href;
let currentRegex;
for (let i = 0; i < blockedDomains.length; i++) {
const blockedDomain = blockedDomains[i].replace('.', '\\.');
currentRegex = new RegExp(
`(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`,
'u',
);
if (!currentRegex.test(currentUrl)) {
return true;
}
}
return false;
}

/**
* Returns a promise that resolves when the DOM is loaded (does not wait for images to load)
*/
async function domIsReady() {
// already loaded
if (['interactive', 'complete'].includes(document.readyState)) {
return;
}
// wait for load
await new Promise((resolve) =>
window.addEventListener('DOMContentLoaded', resolve, { once: true }),
);
}
109 changes: 109 additions & 0 deletions scripts/inpage-bridge/inpage/MobilePortStream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const { inherits } = require('util');
const { Duplex } = require('readable-stream');

const noop = () => undefined;

module.exports = MobilePortStream;

inherits(MobilePortStream, Duplex);

/**
* Creates a stream that's both readable and writable.
* The stream supports arbitrary objects.
*
* @class
* @param {Object} port Remote Port object
*/
function MobilePortStream(port) {
Duplex.call(this, {
objectMode: true,
});
this._name = port.name;
this._targetWindow = window;
this._port = port;
this._origin = location.origin;
window.addEventListener('message', this._onMessage.bind(this), false);
}

/**
* Callback triggered when a message is received from
* the remote Port associated with this Stream.
*
* @private
* @param {Object} msg - Payload from the onMessage listener of Port
*/
MobilePortStream.prototype._onMessage = function (event) {
const msg = event.data;

// validate message
if (this._origin !== '*' && event.origin !== this._origin) {
return;
}
if (!msg || typeof msg !== 'object') {
return;
}
if (!msg.data || typeof msg.data !== 'object') {
return;
}
if (msg.target && msg.target !== this._name) {
return;
}
// Filter outgoing messages
if (msg.data.data && msg.data.data.toNative) {
return;
}

if (Buffer.isBuffer(msg)) {
delete msg._isBuffer;
const data = Buffer.from(msg);
this.push(data);
} else {
this.push(msg);
}
};

/**
* Callback triggered when the remote Port
* associated with this Stream disconnects.
*
* @private
*/
MobilePortStream.prototype._onDisconnect = function () {
this.destroy();
};

/**
* Explicitly sets read operations to a no-op
*/
MobilePortStream.prototype._read = noop;

/**
* Called internally when data should be written to
* this writable stream.
*
* @private
* @param {*} msg Arbitrary object to write
* @param {string} encoding Encoding to use when writing payload
* @param {Function} cb Called when writing is complete or an error occurs
*/
MobilePortStream.prototype._write = function (msg, _encoding, cb) {
try {
if (Buffer.isBuffer(msg)) {
const data = msg.toJSON();
data._isBuffer = true;
window.ReactNativeWebView.postMessage(
JSON.stringify({ ...data, origin: window.location.href }),
);
} else {
if (msg.data) {
msg.data.toNative = true;
}
window.ReactNativeWebView.postMessage(
JSON.stringify({ ...msg, origin: window.location.href }),
);
}
} catch (err) {
return cb(new Error('MobilePortStream - disconnected'));
}
return cb();
};
Loading
Loading