2017-08-04 19:55:00 +02:00
|
|
|
const ethUtil = require('ethereumjs-util')
|
2017-08-09 06:05:59 +02:00
|
|
|
const assert = require('assert')
|
|
|
|
const BN = require('bn.js')
|
2018-04-17 08:03:47 +02:00
|
|
|
const {
|
|
|
|
ENVIRONMENT_TYPE_POPUP,
|
|
|
|
ENVIRONMENT_TYPE_NOTIFICATION,
|
|
|
|
ENVIRONMENT_TYPE_FULLSCREEN,
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
ENVIRONMENT_TYPE_BACKGROUND,
|
2018-08-08 09:00:39 +02:00
|
|
|
PLATFORM_FIREFOX,
|
|
|
|
PLATFORM_OPERA,
|
|
|
|
PLATFORM_CHROME,
|
|
|
|
PLATFORM_EDGE,
|
|
|
|
PLATFORM_BRAVE,
|
2018-04-17 08:03:47 +02:00
|
|
|
} = require('./enums')
|
2017-07-25 22:08:31 +02:00
|
|
|
|
2018-04-16 19:08:04 +02:00
|
|
|
/**
|
|
|
|
* Generates an example stack trace
|
|
|
|
*
|
|
|
|
* @returns {string} A stack trace
|
|
|
|
*
|
|
|
|
*/
|
2017-07-25 22:08:31 +02:00
|
|
|
function getStack () {
|
|
|
|
const stack = new Error('Stack trace generator - not an error').stack
|
|
|
|
return stack
|
|
|
|
}
|
2017-08-04 19:55:00 +02:00
|
|
|
|
2018-04-18 20:45:48 +02:00
|
|
|
/**
|
|
|
|
* Used to determine the window type through which the app is being viewed.
|
|
|
|
* - 'popup' refers to the extension opened through the browser app icon (in top right corner in chrome and firefox)
|
|
|
|
* - 'responsive' refers to the main browser window
|
|
|
|
* - 'notification' refers to the popup that appears in its own window when taking action outside of metamask
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
* - 'background' refers to the background page
|
2018-04-18 20:45:48 +02:00
|
|
|
*
|
|
|
|
* @returns {string} A single word label that represents the type of window through which the app is being viewed
|
|
|
|
*
|
|
|
|
*/
|
2018-04-17 08:03:47 +02:00
|
|
|
const getEnvironmentType = (url = window.location.href) => {
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
const parsedUrl = new URL(url)
|
|
|
|
if (parsedUrl.pathname === '/popup.html') {
|
2018-04-17 08:03:47 +02:00
|
|
|
return ENVIRONMENT_TYPE_POPUP
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
} else if (parsedUrl.pathname === '/home.html') {
|
2018-04-17 08:03:47 +02:00
|
|
|
return ENVIRONMENT_TYPE_FULLSCREEN
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
} else if (parsedUrl.pathname === '/notification.html') {
|
2018-04-17 08:03:47 +02:00
|
|
|
return ENVIRONMENT_TYPE_NOTIFICATION
|
Close window after opening fullscreen (#6966)
* Add background environment type
The `getEnvironmentType` method now checks for the background
environment as well, instead of returning 'notification' for that case.
Instead of adding another regex for the background path, the regexes
for each environment have been replaced with the URL constructor[0].
This is the standard method of parsing URLs, and is available in all
supported browsers.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/URL
* Add note regarding a missing manifest permission
The `url` parameter to `tabs.query(...)` requires the `tabs` permission,
and will be ignored otherwise. We are missing this permission, so that
call does not work.
* Close window after opening full screen
The browser behaviour when opening a new tab differs between Chrome and
Firefox. In the case of a popup, Chrome will close the popup whereas
Firefox will leave it open. In the case of the notification window,
Chrome will move the new tab to the foreground, whereas Firefox will
leave the notification window in the foreground when opening a new tab.
We always want to close the current UI (popup or notification) when
switching to a full-screen view. The only exception to this is when the
switch is triggered from the background, which has no UI.
Closes #6513, #6685
2019-08-08 16:50:32 +02:00
|
|
|
} else {
|
|
|
|
return ENVIRONMENT_TYPE_BACKGROUND
|
2018-04-17 08:03:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-08 09:00:39 +02:00
|
|
|
/**
|
|
|
|
* Returns the platform (browser) where the extension is running.
|
|
|
|
*
|
|
|
|
* @returns {string} the platform ENUM
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
const getPlatform = _ => {
|
|
|
|
const ua = navigator.userAgent
|
|
|
|
if (ua.search('Firefox') !== -1) {
|
|
|
|
return PLATFORM_FIREFOX
|
|
|
|
} else {
|
|
|
|
if (window && window.chrome && window.chrome.ipcRenderer) {
|
|
|
|
return PLATFORM_BRAVE
|
|
|
|
} else if (ua.search('Edge') !== -1) {
|
|
|
|
return PLATFORM_EDGE
|
|
|
|
} else if (ua.search('OPR') !== -1) {
|
|
|
|
return PLATFORM_OPERA
|
|
|
|
} else {
|
|
|
|
return PLATFORM_CHROME
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-16 19:08:04 +02:00
|
|
|
/**
|
|
|
|
* Checks whether a given balance of ETH, represented as a hex string, is sufficient to pay a value plus a gas fee
|
|
|
|
*
|
|
|
|
* @param {object} txParams Contains data about a transaction
|
|
|
|
* @param {string} txParams.gas The gas for a transaction
|
|
|
|
* @param {string} txParams.gasPrice The price per gas for the transaction
|
|
|
|
* @param {string} txParams.value The value of ETH to send
|
|
|
|
* @param {string} hexBalance A balance of ETH represented as a hex string
|
|
|
|
* @returns {boolean} Whether the balance is greater than or equal to the value plus the value of gas times gasPrice
|
|
|
|
*
|
|
|
|
*/
|
2017-08-04 19:55:00 +02:00
|
|
|
function sufficientBalance (txParams, hexBalance) {
|
2017-08-09 06:05:59 +02:00
|
|
|
// validate hexBalance is a hex string
|
|
|
|
assert.equal(typeof hexBalance, 'string', 'sufficientBalance - hexBalance is not a hex string')
|
|
|
|
assert.equal(hexBalance.slice(0, 2), '0x', 'sufficientBalance - hexBalance is not a hex string')
|
|
|
|
|
2017-08-04 19:55:00 +02:00
|
|
|
const balance = hexToBn(hexBalance)
|
|
|
|
const value = hexToBn(txParams.value)
|
|
|
|
const gasLimit = hexToBn(txParams.gas)
|
|
|
|
const gasPrice = hexToBn(txParams.gasPrice)
|
|
|
|
|
|
|
|
const maxCost = value.add(gasLimit.mul(gasPrice))
|
|
|
|
return balance.gte(maxCost)
|
|
|
|
}
|
|
|
|
|
2018-04-16 19:08:04 +02:00
|
|
|
/**
|
|
|
|
* Converts a BN object to a hex string with a '0x' prefix
|
|
|
|
*
|
2018-04-17 05:26:46 +02:00
|
|
|
* @param {BN} inputBn The BN to convert to a hex string
|
|
|
|
* @returns {string} A '0x' prefixed hex string
|
2018-04-16 19:08:04 +02:00
|
|
|
*
|
|
|
|
*/
|
2017-08-04 19:55:00 +02:00
|
|
|
function bnToHex (inputBn) {
|
|
|
|
return ethUtil.addHexPrefix(inputBn.toString(16))
|
|
|
|
}
|
|
|
|
|
2018-04-16 19:08:04 +02:00
|
|
|
/**
|
|
|
|
* Converts a hex string to a BN object
|
|
|
|
*
|
|
|
|
* @param {string} inputHex A number represented as a hex string
|
|
|
|
* @returns {Object} A BN object
|
|
|
|
*
|
|
|
|
*/
|
2017-08-04 19:55:00 +02:00
|
|
|
function hexToBn (inputHex) {
|
|
|
|
return new BN(ethUtil.stripHexPrefix(inputHex), 16)
|
|
|
|
}
|
|
|
|
|
2018-04-16 19:08:04 +02:00
|
|
|
/**
|
|
|
|
* Used to multiply a BN by a fraction
|
|
|
|
*
|
|
|
|
* @param {BN} targetBN The number to multiply by a fraction
|
2018-04-17 05:26:46 +02:00
|
|
|
* @param {number|string} numerator The numerator of the fraction multiplier
|
|
|
|
* @param {number|string} denominator The denominator of the fraction multiplier
|
2018-04-16 19:08:04 +02:00
|
|
|
* @returns {BN} The product of the multiplication
|
|
|
|
*
|
|
|
|
*/
|
2017-08-04 19:55:00 +02:00
|
|
|
function BnMultiplyByFraction (targetBN, numerator, denominator) {
|
|
|
|
const numBN = new BN(numerator)
|
|
|
|
const denomBN = new BN(denominator)
|
|
|
|
return targetBN.mul(numBN).div(denomBN)
|
|
|
|
}
|
2018-04-17 08:03:47 +02:00
|
|
|
|
2018-05-28 23:29:31 +02:00
|
|
|
function applyListeners (listeners, emitter) {
|
|
|
|
Object.keys(listeners).forEach((key) => {
|
|
|
|
emitter.on(key, listeners[key])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeListeners (listeners, emitter) {
|
|
|
|
Object.keys(listeners).forEach((key) => {
|
|
|
|
emitter.removeListener(key, listeners[key])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-08-20 20:52:00 +02:00
|
|
|
function fetchWithTimeout ({ timeout = 120000 } = {}) {
|
|
|
|
return async function _fetch (url, opts) {
|
|
|
|
const abortController = new AbortController()
|
|
|
|
const abortSignal = abortController.signal
|
|
|
|
const f = fetch(url, {
|
|
|
|
...opts,
|
|
|
|
signal: abortSignal,
|
|
|
|
})
|
|
|
|
|
|
|
|
const timer = setTimeout(() => abortController.abort(), timeout)
|
|
|
|
|
|
|
|
try {
|
|
|
|
const res = await f
|
|
|
|
clearTimeout(timer)
|
|
|
|
return res
|
|
|
|
} catch (e) {
|
|
|
|
clearTimeout(timer)
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-17 08:03:47 +02:00
|
|
|
module.exports = {
|
2018-05-28 23:29:31 +02:00
|
|
|
removeListeners,
|
|
|
|
applyListeners,
|
2018-08-08 09:00:39 +02:00
|
|
|
getPlatform,
|
2018-04-17 08:03:47 +02:00
|
|
|
getStack,
|
|
|
|
getEnvironmentType,
|
|
|
|
sufficientBalance,
|
|
|
|
hexToBn,
|
|
|
|
bnToHex,
|
|
|
|
BnMultiplyByFraction,
|
2019-08-20 20:52:00 +02:00
|
|
|
fetchWithTimeout,
|
2018-04-17 08:03:47 +02:00
|
|
|
}
|