mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
9e2e353a24
We inject `web3` globally on most websites. This has been breaking websites that attempted to serialize the `window` object, because any attempt to access certain `web3` properties (such as `web3.eth.mining`) would throw an error. This is because `web3` defined a getter for these properties that would call `.send([method])`, which doesn't work for most methods. An example of a site that this breaks is `Storybook`, when the `@storybook/addon-actions` addon is being used. When using storybook with this addon and with the MetaMask extension installed, actions would not be properly dispatched because an error would be thrown in the attempt to serialize the event (which includes a reference to the `window`). The `web3` global we inject is now defined as non-enumerable, so it will be skipped automatically in any attempt to serialize the `window` object.
82 lines
1.9 KiB
JavaScript
82 lines
1.9 KiB
JavaScript
|
|
// TODO:deprecate:2020
|
|
|
|
export default function setupDappAutoReload (web3, observable) {
|
|
// export web3 as a global, checking for usage
|
|
let reloadInProgress = false
|
|
let lastTimeUsed
|
|
let lastSeenNetwork
|
|
let hasBeenWarned = false
|
|
|
|
const web3Proxy = new Proxy(web3, {
|
|
get: (_web3, key) => {
|
|
// get the time of use
|
|
lastTimeUsed = Date.now()
|
|
// show warning once on web3 access
|
|
if (!hasBeenWarned && key !== 'currentProvider') {
|
|
console.warn(`MetaMask: We will soon stop injecting web3. For more information, see: https://medium.com/metamask/no-longer-injecting-web3-js-4a899ad6e59e`)
|
|
hasBeenWarned = true
|
|
}
|
|
// return value normally
|
|
return _web3[key]
|
|
},
|
|
set: (_web3, key, value) => {
|
|
// set value normally
|
|
_web3[key] = value
|
|
},
|
|
})
|
|
|
|
Object.defineProperty(global, 'web3', {
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true,
|
|
value: web3Proxy,
|
|
})
|
|
|
|
observable.subscribe(function (state) {
|
|
// if the auto refresh on network change is false do not
|
|
// do anything
|
|
if (!window.ethereum.autoRefreshOnNetworkChange) {
|
|
return
|
|
}
|
|
|
|
// if reload in progress, no need to check reload logic
|
|
if (reloadInProgress) {
|
|
return
|
|
}
|
|
|
|
const currentNetwork = state.networkVersion
|
|
|
|
// set the initial network
|
|
if (!lastSeenNetwork) {
|
|
lastSeenNetwork = currentNetwork
|
|
return
|
|
}
|
|
|
|
// skip reload logic if web3 not used
|
|
if (!lastTimeUsed) {
|
|
return
|
|
}
|
|
|
|
// if network did not change, exit
|
|
if (currentNetwork === lastSeenNetwork) {
|
|
return
|
|
}
|
|
|
|
// initiate page reload
|
|
reloadInProgress = true
|
|
const timeSinceUse = Date.now() - lastTimeUsed
|
|
// if web3 was recently used then delay the reloading of the page
|
|
if (timeSinceUse > 500) {
|
|
triggerReset()
|
|
} else {
|
|
setTimeout(triggerReset, 500)
|
|
}
|
|
})
|
|
}
|
|
|
|
// reload the page
|
|
function triggerReset () {
|
|
global.location.reload()
|
|
}
|