Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Commit

Permalink
Update metamask-inpage-provider; remove old functionality (#6)
Browse files Browse the repository at this point in the history
* update inpage-provider

* remove functionality now handled by inpage-provider

* add dev build scripts

* 1.0.1
  • Loading branch information
rekmarks authored Feb 11, 2020
1 parent 374acba commit 947391d
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 293 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ module.exports = {
'@metamask/eslint-config',
'@metamask/eslint-config/config/nodejs',
],
plugins: [
'json',
],
globals: {
Atomics: 'readonly',
Buffer: 'readonly',
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/
node_modules/
*.log
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v10.16.3
195 changes: 102 additions & 93 deletions dist/index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/inpage.js

Large diffs are not rendered by default.

17 changes: 13 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
{
"name": "metamask-mobile-provider",
"version": "1.0.0",
"version": "1.0.1",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:inpage": "cd src/inpage && npx webpack --config webpack.config.js",
"build:dev:inpage": "cd src/inpage && npx webpack --mode=development --config webpack.config.js",
"bundle:inpage": "node src/content-script/wrapper.js",
"bundle:contentscript": "concat-cli -f src/content-script/inpage-bundle.js src/content-script/index.js -o dist/index.js",
"bundle": "yarn build:inpage && yarn bundle:inpage && yarn bundle:contentscript",
"lint": "eslint .",
"lint:fix": "eslint ."
"bundle:dev": "yarn build:dev:inpage && yarn bundle:inpage && yarn bundle:contentscript",
"lint": "eslint . --ext js,json",
"lint:fix": "eslint . --ext js,json --fix"
},
"author": "MetaMask",
"license": "ISC",
"description": "",
"husky": {
"hooks": {
"pre-commit": "yarn bundle"
}
},
"devDependencies": {
"@babel/core": "^7.7.2",
"@babel/plugin-proposal-class-properties": "^7.7.0",
Expand All @@ -23,7 +30,9 @@
"babel-loader": "^8.0.6",
"concat-cli": "^4.0.0",
"eslint": "^6.8.0",
"metamask-inpage-provider": "^3.0.1",
"eslint-plugin-json": "^2.0.1",
"husky": "^4.2.1",
"metamask-inpage-provider": "^4.1.1",
"obj-multiplex": "^1.0.0",
"web3": "0.20.7",
"webpack": "^4.41.2",
Expand Down
11 changes: 8 additions & 3 deletions src/content-script/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
*/
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 (e) {
console.error('MetaMask script injection failed', e)
} catch (err) {
console.error('MetaMask script injection failed', err)
}
}

Expand Down Expand Up @@ -156,7 +161,7 @@ if (shouldInjectWeb3()) {
data.networkVersion !== window.ethereum.networkVersion ||
data.chainId !== window.ethereum.chainId
) {
window.ethereum.publicConfigStore.emit('update', message.data.data)
window.ethereum._publicConfigStore.emit('update', message.data.data)
}
}
})
Expand Down
4 changes: 2 additions & 2 deletions src/content-script/inpage-bundle.js

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions src/content-script/setProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ function setupDappAutoReload (web3, observable) {
lastTimeUsed = Date.now()
// show warning once on web3 access
if (!hasBeenWarned && key !== 'currentProvider') {
console.warn(
'MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider\nhttps://medium.com/metamask/4a899ad6e59e',
)
console.warn(`MetaMask: In Q1 2020, MetaMask will no longer inject web3. For more information, see: https://medium.com/metamask/no-longer-injecting-web3-js-4a899ad6e59e`)
hasBeenWarned = true
}
// return value normally
Expand Down Expand Up @@ -87,15 +85,15 @@ if (typeof window.web3 !== 'undefined') {
Please remove one and try again.`)
}

const web3 = new Web3(window.proxiedInpageProvider)
const web3 = new Web3(window.ethereum)
web3.setProvider = function () {
console.debug('MetaMask - overrode web3.setProvider')
}
console.debug('MetaMask - injected web3')

setupDappAutoReload(web3, window.inpageProvider.publicConfigStore)
setupDappAutoReload(web3, window.ethereum._publicConfigStore)

// set web3 defaultAccount
window.inpageProvider.publicConfigStore.subscribe(state => {
window.ethereum._publicConfigStore.subscribe(state => {
web3.eth.defaultAccount = state.selectedAddress
})
75 changes: 0 additions & 75 deletions src/inpage/createStandardProvider.js

This file was deleted.

126 changes: 26 additions & 100 deletions src/inpage/index.js
Original file line number Diff line number Diff line change
@@ -1,113 +1,33 @@

const MetamaskInpageProvider = require('metamask-inpage-provider')
const createStandardProvider = require('./createStandardProvider').default
const ObjectMultiplex = require('obj-multiplex')
const pump = require('pump')
const MobilePortStream = require('./MobilePortStream')
const ReactNativePostMessageStream = require('./ReactNativePostMessageStream')

let warned = false

const metamaskStream = new ReactNativePostMessageStream({
name: 'inpage',
target: 'contentscript',
})

window.inpageProvider = new MetamaskInpageProvider(metamaskStream)

// compose the inpage provider
// set a high max listener count to avoid unnecesary warnings
window.inpageProvider.setMaxListeners(100)
function setupProvider () {

let warnedOfAutoRefreshDeprecation = false
// augment the provider with its enable method
window.inpageProvider.enable = function ({ force } = {}) {
if (
!warnedOfAutoRefreshDeprecation &&
window.inpageProvider.autoRefreshOnNetworkChange
) {
console.warn(`MetaMask: MetaMask will soon stop reloading pages on network change.
If you rely upon this behavior, add a 'networkChanged' event handler to trigger the reload manually: https://metamask.github.io/metamask-docs/API_Reference/Ethereum_Provider#ethereum.on(eventname%2C-callback)
Set 'ethereum.autoRefreshOnNetworkChange' to 'false' to silence this warning: https://metamask.github.io/metamask-docs/API_Reference/Ethereum_Provider#ethereum.autorefreshonnetworkchange'
`)
warnedOfAutoRefreshDeprecation = true
}
return new Promise((resolve, reject) => {
window.inpageProvider.sendAsync({ method: 'eth_requestAccounts', params: (force && [force] || []) }, (error, response) => {
if (error || response.error) {
reject(error || response.error)
} else {
resolve(response.result)
}
})
})
}
const inpageProvider = new MetamaskInpageProvider(metamaskStream, false)

// give the dapps control of a refresh they can toggle this off on the window.ethereum
// this will be default true so it does not break any old apps.
window.inpageProvider.autoRefreshOnNetworkChange = true
// compose the inpage provider
// set a high max listener count to avoid unnecesary warnings
inpageProvider.setMaxListeners(100)


const getPublicConfigWhenReady = async () => {
const store = window.inpageProvider.publicConfigStore
let state = store.getState()
// if state is missing, wait for first update
if (!state.networkVersion) {
state = await new Promise(resolve => store.once('update', resolve))
}
return state
// Work around for [email protected] deleting the bound `sendAsync` but not the unbound
// `sendAsync` method on the prototype, causing `this` reference issues
window.ethereum = new Proxy(inpageProvider, {
// straight up lie that we deleted the property so that it doesnt
// throw an error in strict mode
deleteProperty: () => true,
})
}

// add metamask-specific convenience methods
window.inpageProvider._metamask = new Proxy({
/**
* Synchronously determines if this domain is currently enabled, with a potential false negative if called to soon
*
* @returns {boolean} - returns true if this domain is currently enabled
*/
isEnabled: function () {
const { isEnabled } = window.inpageProvider.publicConfigStore.getState()
return Boolean(isEnabled)
},

/**
* Asynchronously determines if this domain is currently enabled
*
* @returns {Promise<boolean>} - Promise resolving to true if this domain is currently enabled
*/
isApproved: async function () {
const { isEnabled } = await getPublicConfigWhenReady()
return Boolean(isEnabled)
},

/**
* Determines if MetaMask is unlocked by the user
*
* @returns {Promise<boolean>} - Promise resolving to true if MetaMask is currently unlocked
*/
isUnlocked: async function () {
const { isUnlocked } = await getPublicConfigWhenReady()
return Boolean(isUnlocked)
},
}, {
get: function (obj, prop) {
!warned && console.warn('Heads up! ethereum._metamask exposes methods that have ' +
'not been standardized yet. This means that these methods may not be implemented ' +
'in other dapp browsers and may be removed from MetaMask in the future.')
warned = true
return obj[prop]
},
})

// Work around for [email protected] deleting the bound `sendAsync` but not the unbound
// `sendAsync` method on the prototype, causing `this` reference issues
window.proxiedInpageProvider = new Proxy(window.inpageProvider, {
// straight up lie that we deleted the property so that it doesnt
// throw an error in strict mode
deleteProperty: () => true,
})

window.ethereum = createStandardProvider(window.proxiedInpageProvider)
setupProvider()

window.setupStreams = function () {
// the transport-specific streams for communication between inpage and background
Expand All @@ -120,7 +40,7 @@ window.setupStreams = function () {
name: 'contentscript',
})

// create and connect channel muxers
// create and connect channel muxes
// so we can handle the channels individually
const pageMux = new ObjectMultiplex()
pageMux.setMaxListeners(25)
Expand All @@ -141,12 +61,18 @@ window.setupStreams = function () {
)

// forward communication across inpage-background for these channels only
forwardTrafficBetweenMuxers('provider', pageMux, appMux)
forwardTrafficBetweenMuxers('publicConfig', pageMux, appMux)

forwardTrafficBetweenMuxes('provider', pageMux, appMux)
forwardTrafficBetweenMuxes('publicConfig', pageMux, appMux)
}

function forwardTrafficBetweenMuxers (channelName, muxA, muxB) {
/**
* Set up two-way communication between muxes for a single, named channel.
*
* @param {string} channelName - The name of the channel.
* @param {ObjectMultiplex} muxA - The first mux.
* @param {ObjectMultiplex} muxB - The second mux.
*/
function forwardTrafficBetweenMuxes (channelName, muxA, muxB) {
const channelA = muxA.createStream(channelName)
const channelB = muxB.createStream(channelName)
pump(
Expand All @@ -160,8 +86,8 @@ function forwardTrafficBetweenMuxers (channelName, muxA, muxB) {
/**
* Error handler for page to extension stream disconnections
*
* @param {string} remoteLabel Remote stream name
* @param {Error} err Stream connection error
* @param {string} remoteLabel - Remote stream name
* @param {Error} err - Stream connection error
*/
function logStreamDisconnectWarning (remoteLabel, err) {
let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`
Expand Down
11 changes: 10 additions & 1 deletion src/inpage/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const path = require('path')

// This is main configuration object.
// Here you write different options and tell Webpack what to do
module.exports = {
const config = {

// Path to your entry point. From this file Webpack will begin his work
entry: './index.js',
Expand Down Expand Up @@ -37,3 +37,12 @@ module.exports = {
],
},
}

module.exports = (_env, argv) => {

if (argv.mode === 'development') {
config.mode = 'development'
}

return config
}
Loading

0 comments on commit 947391d

Please sign in to comment.