1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-26 12:29:06 +01:00

Merge remote-tracking branch 'origin/develop' into sync-master

* origin/develop:
  add new typography component (#10197)
  @metamask/inpage-provider@8.0.3 (#10219)
  Add NETWORK_TYPE_RPC constant (#10203)
  Further improve organization of constants (#10200)
  add includePaths to sass-loader in storybook (#10213)
  Disable the swaps submit button after the first time it is clicked (#10162)
  Remove default to 18 decimals in quotesToRenderableData method (#10212)
  use dart sass, and update related modules (#10208)
  Fetch with a timeout everywhere (#10101)
  Make hiring link a link on text (#10206)
  improve design system scss (#10193)
  zh_TW: Translate buy, assets, activity (#10207)
  Update TW term 乙太 -> 以太 (#10191)
  Fix hardware account selection (#10198)
  Add hiring note to the README (#10190)
  drop the fox in about (#10174)
This commit is contained in:
Mark Stacey 2021-01-20 18:55:04 -03:30
commit 774b537a9b
110 changed files with 627 additions and 335 deletions

View File

@ -7,3 +7,4 @@ app/vendor/**
.nyc_output/** .nyc_output/**
.vscode/** .vscode/**
test/e2e/send-eth-with-private-key-test/** test/e2e/send-eth-with-private-key-test/**
*.scss

View File

@ -7,7 +7,7 @@ module.exports = {
addons: [ addons: [
'@storybook/addon-knobs', '@storybook/addon-knobs',
'@storybook/addon-actions', '@storybook/addon-actions',
'@storybook/addon-backgrounds' '@storybook/addon-backgrounds',
], ],
webpackFinal: async (config) => { webpackFinal: async (config) => {
config.module.strictExportPresence = true config.module.strictExportPresence = true
@ -27,18 +27,29 @@ module.exports = {
loader: 'sass-loader', loader: 'sass-loader',
options: { options: {
sourceMap: true, sourceMap: true,
implementation: require('sass'),
sassOptions: {
includePaths: ['ui/app/css/'],
},
}, },
}, },
], ],
}) })
config.plugins.push(new CopyWebpackPlugin({ config.plugins.push(
patterns: [ new CopyWebpackPlugin({
{ patterns: [
from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), {
to: path.join('fonts', 'fontawesome'), from: path.join(
}, 'node_modules',
], '@fortawesome',
})) 'fontawesome-free',
'webfonts',
),
to: path.join('fonts', 'fontawesome'),
},
],
}),
)
return config return config
}, },
} }

View File

@ -1,5 +1,8 @@
# MetaMask Browser Extension # MetaMask Browser Extension
Hey! We are hiring JavaScript Engineers! [Apply here](https://boards.greenhouse.io/consensys/jobs/2572388)!
---
You can find the latest version of MetaMask on [our official website](https://metamask.io/). For help using MetaMask, visit our [User Support Site](https://metamask.zendesk.com/hc/en-us). You can find the latest version of MetaMask on [our official website](https://metamask.io/). For help using MetaMask, visit our [User Support Site](https://metamask.zendesk.com/hc/en-us).
For [general questions](https://metamask.zendesk.com/hc/en-us/community/topics/360000682532-General), [feature requests](https://metamask.zendesk.com/hc/en-us/community/topics/360000682552-Feature-Requests-Ideas), or [developer questions](https://metamask.zendesk.com/hc/en-us/community/topics/360001751291-Developer-Questions), visit our [Community Forum](https://metamask.zendesk.com/hc/en-us/community/topics). For [general questions](https://metamask.zendesk.com/hc/en-us/community/topics/360000682532-General), [feature requests](https://metamask.zendesk.com/hc/en-us/community/topics/360000682552-Feature-Requests-Ideas), or [developer questions](https://metamask.zendesk.com/hc/en-us/community/topics/360001751291-Developer-Questions), visit our [Community Forum](https://metamask.zendesk.com/hc/en-us/community/topics).

View File

@ -19,6 +19,12 @@ import extension from 'extensionizer'
import { storeAsStream, storeTransformStream } from '@metamask/obs-store' import { storeAsStream, storeTransformStream } from '@metamask/obs-store'
import PortStream from 'extension-port-stream' import PortStream from 'extension-port-stream'
import { captureException } from '@sentry/browser' import { captureException } from '@sentry/browser'
import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
} from '../../shared/constants/app'
import migrations from './migrations' import migrations from './migrations'
import Migrator from './lib/migrator' import Migrator from './lib/migrator'
import ExtensionPlatform from './platforms/extension' import ExtensionPlatform from './platforms/extension'
@ -31,12 +37,6 @@ import rawFirstTimeState from './first-time-state'
import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code' import getFirstPreferredLangCode from './lib/get-first-preferred-lang-code'
import getObjStructure from './lib/getObjStructure' import getObjStructure from './lib/getObjStructure'
import setupEnsIpfsResolver from './lib/ens-ipfs/setup' import setupEnsIpfsResolver from './lib/ens-ipfs/setup'
import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
} from './lib/enums'
/* eslint-enable import/first */ /* eslint-enable import/first */
const { sentry } = global const { sentry } = global

View File

@ -2,12 +2,11 @@ import Web3 from 'web3'
import contracts from '@metamask/contract-metadata' import contracts from '@metamask/contract-metadata'
import { warn } from 'loglevel' import { warn } from 'loglevel'
import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi' import SINGLE_CALL_BALANCES_ABI from 'single-call-balance-checker-abi'
import { MAINNET_CHAIN_ID } from './network/enums' import { MAINNET_CHAIN_ID } from '../../../shared/constants/network'
import { SINGLE_CALL_BALANCES_ADDRESS } from '../constants/contracts'
// By default, poll every 3 minutes // By default, poll every 3 minutes
const DEFAULT_INTERVAL = 180 * 1000 const DEFAULT_INTERVAL = 180 * 1000
const SINGLE_CALL_BALANCES_ADDRESS =
'0xb1f8e55c7f64d203c1400b9d8555d050f94adf39'
/** /**
* A controller that polls for token exchange * A controller that polls for token exchange

View File

@ -3,7 +3,7 @@ import log from 'loglevel'
import BN from 'bn.js' import BN from 'bn.js'
import createId from '../lib/random-id' import createId from '../lib/random-id'
import { bnToHex } from '../lib/util' import { bnToHex } from '../lib/util'
import fetchWithTimeout from '../lib/fetch-with-timeout' import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'
import { import {
TRANSACTION_CATEGORIES, TRANSACTION_CATEGORIES,
@ -22,11 +22,9 @@ import {
RINKEBY_CHAIN_ID, RINKEBY_CHAIN_ID,
ROPSTEN, ROPSTEN,
ROPSTEN_CHAIN_ID, ROPSTEN_CHAIN_ID,
} from './network/enums' } from '../../../shared/constants/network'
const fetch = fetchWithTimeout({ const fetchWithTimeout = getFetchWithTimeout(30000)
timeout: 30000,
})
/** /**
* This controller is responsible for retrieving incoming transactions. Etherscan is polled once every block to check * This controller is responsible for retrieving incoming transactions. Etherscan is polled once every block to check
@ -227,7 +225,7 @@ export default class IncomingTransactionsController {
if (fromBlock) { if (fromBlock) {
url += `&startBlock=${parseInt(fromBlock, 10)}` url += `&startBlock=${parseInt(fromBlock, 10)}`
} }
const response = await fetch(url) const response = await fetchWithTimeout(url)
const parsedResponse = await response.json() const parsedResponse = await response.json()
return { return {

View File

@ -1,7 +1,7 @@
import { merge, omit } from 'lodash' import { merge, omit } from 'lodash'
import { ObservableStore } from '@metamask/obs-store' import { ObservableStore } from '@metamask/obs-store'
import { bufferToHex, sha3 } from 'ethereumjs-util' import { bufferToHex, sha3 } from 'ethereumjs-util'
import { ENVIRONMENT_TYPE_BACKGROUND } from '../lib/enums' import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'
import { import {
METAMETRICS_ANONYMOUS_ID, METAMETRICS_ANONYMOUS_ID,
METAMETRICS_BACKGROUND_PAGE_OBJECT, METAMETRICS_BACKGROUND_PAGE_OBJECT,

View File

@ -8,7 +8,7 @@ import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddlewa
import createInfuraMiddleware from 'eth-json-rpc-infura' import createInfuraMiddleware from 'eth-json-rpc-infura'
import BlockTracker from 'eth-block-tracker' import BlockTracker from 'eth-block-tracker'
import { NETWORK_TYPE_TO_ID_MAP } from './enums' import { NETWORK_TYPE_TO_ID_MAP } from '../../../../shared/constants/network'
export default function createInfuraClient({ network, projectId }) { export default function createInfuraClient({ network, projectId }) {
const infuraMiddleware = createInfuraMiddleware({ const infuraMiddleware = createInfuraMiddleware({

View File

@ -9,25 +9,25 @@ import {
createEventEmitterProxy, createEventEmitterProxy,
} from 'swappable-obj-proxy' } from 'swappable-obj-proxy'
import EthQuery from 'eth-query' import EthQuery from 'eth-query'
import createMetamaskMiddleware from './createMetamaskMiddleware'
import createInfuraClient from './createInfuraClient'
import createJsonRpcClient from './createJsonRpcClient'
import { import {
RINKEBY, RINKEBY,
MAINNET, MAINNET,
INFURA_PROVIDER_TYPES, INFURA_PROVIDER_TYPES,
NETWORK_TYPE_RPC,
NETWORK_TYPE_TO_ID_MAP, NETWORK_TYPE_TO_ID_MAP,
MAINNET_CHAIN_ID, MAINNET_CHAIN_ID,
RINKEBY_CHAIN_ID, RINKEBY_CHAIN_ID,
} from './enums' } from '../../../../shared/constants/network'
import createMetamaskMiddleware from './createMetamaskMiddleware'
import createInfuraClient from './createInfuraClient'
import createJsonRpcClient from './createJsonRpcClient'
const env = process.env.METAMASK_ENV const env = process.env.METAMASK_ENV
let defaultProviderConfigOpts let defaultProviderConfigOpts
if (process.env.IN_TEST === 'true') { if (process.env.IN_TEST === 'true') {
defaultProviderConfigOpts = { defaultProviderConfigOpts = {
type: 'rpc', type: NETWORK_TYPE_RPC,
rpcUrl: 'http://localhost:8545', rpcUrl: 'http://localhost:8545',
chainId: '0x539', chainId: '0x539',
nickname: 'Localhost 8545', nickname: 'Localhost 8545',
@ -161,7 +161,7 @@ export default class NetworkController extends EventEmitter {
setRpcTarget(rpcUrl, chainId, ticker = 'ETH', nickname = '', rpcPrefs) { setRpcTarget(rpcUrl, chainId, ticker = 'ETH', nickname = '', rpcPrefs) {
this.setProviderConfig({ this.setProviderConfig({
type: 'rpc', type: NETWORK_TYPE_RPC,
rpcUrl, rpcUrl,
chainId, chainId,
ticker, ticker,
@ -173,8 +173,8 @@ export default class NetworkController extends EventEmitter {
async setProviderType(type, rpcUrl = '', ticker = 'ETH', nickname = '') { async setProviderType(type, rpcUrl = '', ticker = 'ETH', nickname = '') {
assert.notEqual( assert.notEqual(
type, type,
'rpc', NETWORK_TYPE_RPC,
`NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`, `NetworkController - cannot call "setProviderType" with type "${NETWORK_TYPE_RPC}". Use "setRpcTarget"`,
) )
assert( assert(
INFURA_PROVIDER_TYPES.includes(type), INFURA_PROVIDER_TYPES.includes(type),
@ -209,7 +209,7 @@ export default class NetworkController extends EventEmitter {
getNetworkIdentifier() { getNetworkIdentifier() {
const provider = this.providerStore.getState() const provider = this.providerStore.getState()
return provider.type === 'rpc' ? provider.rpcUrl : provider.type return provider.type === NETWORK_TYPE_RPC ? provider.rpcUrl : provider.type
} }
// //
@ -228,7 +228,7 @@ export default class NetworkController extends EventEmitter {
if (isInfura) { if (isInfura) {
this._configureInfuraProvider(type, this._infuraProjectId) this._configureInfuraProvider(type, this._infuraProjectId)
// url-based rpc endpoints // url-based rpc endpoints
} else if (type === 'rpc') { } else if (type === NETWORK_TYPE_RPC) {
this._configureStandardProvider(rpcUrl, chainId) this._configureStandardProvider(rpcUrl, chainId)
} else { } else {
throw new Error( throw new Error(

View File

@ -1,4 +1,4 @@
import { NETWORK_TO_NAME_MAP } from './enums' import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network'
export const getNetworkDisplayName = (key) => NETWORK_TO_NAME_MAP[key] export const getNetworkDisplayName = (key) => NETWORK_TO_NAME_MAP[key]

View File

@ -10,11 +10,6 @@ export const METADATA_STORE_KEY = 'domainMetadata'
export const METADATA_CACHE_MAX_SIZE = 100 export const METADATA_CACHE_MAX_SIZE = 100
export const CAVEAT_NAMES = {
exposedAccounts: 'exposedAccounts',
primaryAccountOnly: 'primaryAccountOnly',
}
export const CAVEAT_TYPES = { export const CAVEAT_TYPES = {
limitResponseLength: 'limitResponseLength', limitResponseLength: 'limitResponseLength',
filterResponse: 'filterResponse', filterResponse: 'filterResponse',

View File

@ -6,10 +6,7 @@ import { CapabilitiesController as RpcCap } from 'rpc-cap'
import { ethErrors } from 'eth-json-rpc-errors' import { ethErrors } from 'eth-json-rpc-errors'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import createPermissionsMethodMiddleware from './permissionsMethodMiddleware' import { CAVEAT_NAMES } from '../../../../shared/constants/permissions'
import PermissionsLogController from './permissionsLog'
// Methods that do not require any permissions to use:
import { import {
APPROVAL_TYPE, APPROVAL_TYPE,
SAFE_METHODS, // methods that do not require any permissions to use SAFE_METHODS, // methods that do not require any permissions to use
@ -18,11 +15,13 @@ import {
METADATA_CACHE_MAX_SIZE, METADATA_CACHE_MAX_SIZE,
LOG_STORE_KEY, LOG_STORE_KEY,
HISTORY_STORE_KEY, HISTORY_STORE_KEY,
CAVEAT_NAMES,
NOTIFICATION_NAMES, NOTIFICATION_NAMES,
CAVEAT_TYPES, CAVEAT_TYPES,
} from './enums' } from './enums'
import createPermissionsMethodMiddleware from './permissionsMethodMiddleware'
import PermissionsLogController from './permissionsLog'
// instanbul ignore next // instanbul ignore next
const noop = () => undefined const noop = () => undefined

View File

@ -1,6 +1,6 @@
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { CAVEAT_NAMES } from '../../../../shared/constants/permissions'
import { import {
CAVEAT_NAMES,
HISTORY_STORE_KEY, HISTORY_STORE_KEY,
LOG_IGNORE_METHODS, LOG_IGNORE_METHODS,
LOG_LIMIT, LOG_LIMIT,

View File

@ -7,7 +7,7 @@ import ethers from 'ethers'
import log from 'loglevel' import log from 'loglevel'
import { isPrefixedFormattedHexString } from '../lib/util' import { isPrefixedFormattedHexString } from '../lib/util'
import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens' import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens'
import { NETWORK_TYPE_TO_ID_MAP } from './network/enums' import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network'
export default class PreferencesController { export default class PreferencesController {
/** /**

View File

@ -2,6 +2,9 @@ import { ObservableStore } from '@metamask/obs-store'
import log from 'loglevel' import log from 'loglevel'
import { normalize as normalizeAddress } from 'eth-sig-util' import { normalize as normalizeAddress } from 'eth-sig-util'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'
const fetchWithTimeout = getFetchWithTimeout(30000)
// By default, poll every 3 minutes // By default, poll every 3 minutes
const DEFAULT_INTERVAL = 180 * 1000 const DEFAULT_INTERVAL = 180 * 1000
@ -34,7 +37,7 @@ export default class TokenRatesController {
const query = `contract_addresses=${pairs}&vs_currencies=${nativeCurrency}` const query = `contract_addresses=${pairs}&vs_currencies=${nativeCurrency}`
if (this._tokens.length > 0) { if (this._tokens.length > 0) {
try { try {
const response = await window.fetch( const response = await fetchWithTimeout(
`https://api.coingecko.com/api/v3/simple/token_price/ethereum?${query}`, `https://api.coingecko.com/api/v3/simple/token_price/ethereum?${query}`,
) )
const prices = await response.json() const prices = await response.json()

View File

@ -19,14 +19,14 @@ import {
RINKEBY_CHAIN_ID, RINKEBY_CHAIN_ID,
ROPSTEN_CHAIN_ID, ROPSTEN_CHAIN_ID,
KOVAN_CHAIN_ID, KOVAN_CHAIN_ID,
} from '../controllers/network/enums' } from '../../../shared/constants/network'
import { import {
SINGLE_CALL_BALANCES_ADDRESS, SINGLE_CALL_BALANCES_ADDRESS,
SINGLE_CALL_BALANCES_ADDRESS_RINKEBY, SINGLE_CALL_BALANCES_ADDRESS_RINKEBY,
SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN, SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN,
SINGLE_CALL_BALANCES_ADDRESS_KOVAN, SINGLE_CALL_BALANCES_ADDRESS_KOVAN,
} from '../controllers/network/contract-addresses' } from '../constants/contracts'
import { bnToHex } from './util' import { bnToHex } from './util'
/** /**

View File

@ -3,9 +3,9 @@ import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-rpc-errors' import { ethErrors } from 'eth-json-rpc-errors'
import log from 'loglevel' import log from 'loglevel'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
import { addHexPrefix } from './util' import { addHexPrefix } from './util'
import createId from './random-id' import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
const hexRe = /^[0-9A-Fa-f]+$/gu const hexRe = /^[0-9A-Fa-f]+$/gu

View File

@ -2,8 +2,8 @@ import EventEmitter from 'events'
import { ObservableStore } from '@metamask/obs-store' import { ObservableStore } from '@metamask/obs-store'
import { ethErrors } from 'eth-json-rpc-errors' import { ethErrors } from 'eth-json-rpc-errors'
import log from 'loglevel' import log from 'loglevel'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
import createId from './random-id' import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
/** /**
* Represents, and contains data about, an 'eth_getEncryptionPublicKey' type request. These are created when * Represents, and contains data about, an 'eth_getEncryptionPublicKey' type request. These are created when

View File

@ -1,6 +1,9 @@
import extension from 'extensionizer' import extension from 'extensionizer'
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
import resolveEnsToIpfsContentId from './resolver' import resolveEnsToIpfsContentId from './resolver'
const fetchWithTimeout = getFetchWithTimeout(30000)
const supportedTopLevelDomains = ['eth'] const supportedTopLevelDomains = ['eth']
export default function setupEnsIpfsResolver({ export default function setupEnsIpfsResolver({
@ -55,7 +58,9 @@ export default function setupEnsIpfsResolver({
)}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}` )}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}`
try { try {
// check if ipfs gateway has result // check if ipfs gateway has result
const response = await window.fetch(resolvedUrl, { method: 'HEAD' }) const response = await fetchWithTimeout(resolvedUrl, {
method: 'HEAD',
})
if (response.status === 200) { if (response.status === 200) {
url = resolvedUrl url = resolvedUrl
} }

View File

@ -2,8 +2,8 @@ import EventEmitter from 'events'
import { ObservableStore } from '@metamask/obs-store' import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-rpc-errors' import { ethErrors } from 'eth-json-rpc-errors'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
import createId from './random-id' import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
/** /**
* Represents, and contains data about, an 'eth_sign' type signature request. These are created when a signature for * Represents, and contains data about, an 'eth_sign' type signature request. These are created when a signature for

View File

@ -1,4 +1,7 @@
import log from 'loglevel' import log from 'loglevel'
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'
const fetchWithTimeout = getFetchWithTimeout(30000)
const FIXTURE_SERVER_HOST = 'localhost' const FIXTURE_SERVER_HOST = 'localhost'
const FIXTURE_SERVER_PORT = 12345 const FIXTURE_SERVER_PORT = 12345
@ -24,7 +27,7 @@ export default class ReadOnlyNetworkStore {
*/ */
async _init() { async _init() {
try { try {
const response = await window.fetch(FIXTURE_SERVER_URL) const response = await fetchWithTimeout(FIXTURE_SERVER_URL)
if (response.ok) { if (response.ok) {
this._state = await response.json() this._state = await response.json()
} }

View File

@ -3,9 +3,9 @@ import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-rpc-errors' import { ethErrors } from 'eth-json-rpc-errors'
import log from 'loglevel' import log from 'loglevel'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
import { addHexPrefix } from './util' import { addHexPrefix } from './util'
import createId from './random-id' import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
const hexRe = /^[0-9A-Fa-f]+$/gu const hexRe = /^[0-9A-Fa-f]+$/gu

View File

@ -1,4 +1,4 @@
import { MESSAGE_TYPE } from '../../enums' import { MESSAGE_TYPE } from '../../../../../shared/constants/app'
/** /**
* This RPC method gets background state relevant to the provider. * This RPC method gets background state relevant to the provider.

View File

@ -1,4 +1,4 @@
import { MESSAGE_TYPE } from '../../enums' import { MESSAGE_TYPE } from '../../../../../shared/constants/app'
/** /**
* This RPC method is called by the inpage provider whenever it detects the * This RPC method is called by the inpage provider whenever it detects the

View File

@ -1,4 +1,4 @@
import { MESSAGE_TYPE } from '../../enums' import { MESSAGE_TYPE } from '../../../../../shared/constants/app'
const watchAsset = { const watchAsset = {
methodNames: [MESSAGE_TYPE.WATCH_ASSET, MESSAGE_TYPE.WATCH_ASSET_LEGACY], methodNames: [MESSAGE_TYPE.WATCH_ASSET, MESSAGE_TYPE.WATCH_ASSET_LEGACY],

View File

@ -6,8 +6,8 @@ import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util'
import { isValidAddress } from 'ethereumjs-util' import { isValidAddress } from 'ethereumjs-util'
import log from 'loglevel' import log from 'loglevel'
import jsonschema from 'jsonschema' import jsonschema from 'jsonschema'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
import createId from './random-id' import createId from './random-id'
import { MESSAGE_TYPE } from './enums'
/** /**
* Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a * Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a

View File

@ -14,7 +14,7 @@ import {
PLATFORM_CHROME, PLATFORM_CHROME,
PLATFORM_EDGE, PLATFORM_EDGE,
PLATFORM_BRAVE, PLATFORM_BRAVE,
} from './enums' } from '../../../shared/constants/app'
/** /**
* @see {@link getEnvironmentType} * @see {@link getEnvironmentType}

View File

@ -1,5 +1,5 @@
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { NETWORK_TYPE_TO_ID_MAP } from '../controllers/network/enums' import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network'
const version = 51 const version = 51

View File

@ -1,7 +1,7 @@
import extension from 'extensionizer' import extension from 'extensionizer'
import { createExplorerLink as explorerLink } from '@metamask/etherscan-link' import { createExplorerLink as explorerLink } from '@metamask/etherscan-link'
import { getEnvironmentType, checkForError } from '../lib/util' import { getEnvironmentType, checkForError } from '../lib/util'
import { ENVIRONMENT_TYPE_BACKGROUND } from '../lib/enums' import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'
import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction' import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'
export default class ExtensionPlatform { export default class ExtensionPlatform {

View File

@ -12,12 +12,12 @@ import EthQuery from 'eth-query'
import StreamProvider from 'web3-stream-provider' import StreamProvider from 'web3-stream-provider'
import log from 'loglevel' import log from 'loglevel'
import launchMetaMaskUi from '../../ui' import launchMetaMaskUi from '../../ui'
import ExtensionPlatform from './platforms/extension'
import { setupMultiplex } from './lib/stream-utils'
import { import {
ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
} from './lib/enums' } from '../../shared/constants/app'
import ExtensionPlatform from './platforms/extension'
import { setupMultiplex } from './lib/stream-utils'
import { getEnvironmentType } from './lib/util' import { getEnvironmentType } from './lib/util'
start().catch(log.error) start().catch(log.error)

View File

@ -1,7 +1,7 @@
const pify = require('pify') const pify = require('pify')
const gulp = require('gulp') const gulp = require('gulp')
const sass = require('gulp-sass') const sass = require('gulp-sass')
sass.compiler = require('node-sass') sass.compiler = require('sass')
const autoprefixer = require('gulp-autoprefixer') const autoprefixer = require('gulp-autoprefixer')
const gulpStylelint = require('gulp-stylelint') const gulpStylelint = require('gulp-stylelint')
const watch = require('gulp-watch') const watch = require('gulp-watch')

View File

@ -246,7 +246,7 @@
"gulp-rename": "^2.0.0", "gulp-rename": "^2.0.0",
"gulp-replace": "^1.0.0", "gulp-replace": "^1.0.0",
"gulp-rtlcss": "^1.4.0", "gulp-rtlcss": "^1.4.0",
"gulp-sass": "^4.0.0", "gulp-sass": "^4.1.0",
"gulp-sourcemaps": "^2.6.0", "gulp-sourcemaps": "^2.6.0",
"gulp-stylelint": "^13.0.0", "gulp-stylelint": "^13.0.0",
"gulp-terser-js": "^5.2.2", "gulp-terser-js": "^5.2.2",
@ -259,7 +259,6 @@
"mocha": "^7.2.0", "mocha": "^7.2.0",
"nock": "^9.0.14", "nock": "^9.0.14",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"node-sass": "^4.14.1",
"nyc": "^15.0.0", "nyc": "^15.0.0",
"polyfill-crypto.getrandomvalues": "^1.0.0", "polyfill-crypto.getrandomvalues": "^1.0.0",
"prettier": "^2.1.1", "prettier": "^2.1.1",
@ -275,7 +274,8 @@
"remote-redux-devtools": "^0.5.16", "remote-redux-devtools": "^0.5.16",
"remotedev-server": "^0.3.1", "remotedev-server": "^0.3.1",
"resolve-url-loader": "^3.1.2", "resolve-url-loader": "^3.1.2",
"sass-loader": "^7.0.1", "sass": "^1.32.4",
"sass-loader": "^10.1.1",
"selenium-webdriver": "4.0.0-alpha.7", "selenium-webdriver": "4.0.0-alpha.7",
"serve-handler": "^6.1.2", "serve-handler": "^6.1.2",
"ses": "0.11.0", "ses": "0.11.0",

View File

@ -6,19 +6,18 @@
* background - The background process that powers the extension * background - The background process that powers the extension
* @typedef {'popup' | 'notification' | 'fullscreen' | 'background'} EnvironmentType * @typedef {'popup' | 'notification' | 'fullscreen' | 'background'} EnvironmentType
*/ */
export const ENVIRONMENT_TYPE_POPUP = 'popup'
export const ENVIRONMENT_TYPE_NOTIFICATION = 'notification'
export const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen'
export const ENVIRONMENT_TYPE_BACKGROUND = 'background'
const ENVIRONMENT_TYPE_POPUP = 'popup' export const PLATFORM_BRAVE = 'Brave'
const ENVIRONMENT_TYPE_NOTIFICATION = 'notification' export const PLATFORM_CHROME = 'Chrome'
const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen' export const PLATFORM_EDGE = 'Edge'
const ENVIRONMENT_TYPE_BACKGROUND = 'background' export const PLATFORM_FIREFOX = 'Firefox'
export const PLATFORM_OPERA = 'Opera'
const PLATFORM_BRAVE = 'Brave' export const MESSAGE_TYPE = {
const PLATFORM_CHROME = 'Chrome'
const PLATFORM_EDGE = 'Edge'
const PLATFORM_FIREFOX = 'Firefox'
const PLATFORM_OPERA = 'Opera'
const MESSAGE_TYPE = {
ETH_DECRYPT: 'eth_decrypt', ETH_DECRYPT: 'eth_decrypt',
ETH_GET_ENCRYPTION_PUBLIC_KEY: 'eth_getEncryptionPublicKey', ETH_GET_ENCRYPTION_PUBLIC_KEY: 'eth_getEncryptionPublicKey',
ETH_SIGN: 'eth_sign', ETH_SIGN: 'eth_sign',
@ -29,16 +28,3 @@ const MESSAGE_TYPE = {
WATCH_ASSET: 'wallet_watchAsset', WATCH_ASSET: 'wallet_watchAsset',
WATCH_ASSET_LEGACY: 'metamask_watchAsset', WATCH_ASSET_LEGACY: 'metamask_watchAsset',
} }
export {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_BACKGROUND,
MESSAGE_TYPE,
PLATFORM_BRAVE,
PLATFORM_CHROME,
PLATFORM_EDGE,
PLATFORM_FIREFOX,
PLATFORM_OPERA,
}

View File

@ -1,6 +1,6 @@
// Type Imports // Type Imports
/** /**
* @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType * @typedef {import('../../shared/constants/app').EnvironmentType} EnvironmentType
*/ */
// Type Declarations // Type Declarations

View File

@ -3,6 +3,7 @@ export const RINKEBY = 'rinkeby'
export const KOVAN = 'kovan' export const KOVAN = 'kovan'
export const MAINNET = 'mainnet' export const MAINNET = 'mainnet'
export const GOERLI = 'goerli' export const GOERLI = 'goerli'
export const NETWORK_TYPE_RPC = 'rpc'
export const MAINNET_NETWORK_ID = '1' export const MAINNET_NETWORK_ID = '1'
export const ROPSTEN_NETWORK_ID = '3' export const ROPSTEN_NETWORK_ID = '3'

View File

@ -0,0 +1,4 @@
export const CAVEAT_NAMES = {
exposedAccounts: 'exposedAccounts',
primaryAccountOnly: 'primaryAccountOnly',
}

View File

@ -1,4 +1,10 @@
const fetchWithTimeout = ({ timeout = 120000 } = {}) => { import { memoize } from 'lodash'
const getFetchWithTimeout = memoize((timeout) => {
if (!Number.isInteger(timeout) || timeout < 1) {
throw new Error('Must specify positive integer timeout.')
}
return async function _fetch(url, opts) { return async function _fetch(url, opts) {
const abortController = new window.AbortController() const abortController = new window.AbortController()
const { signal } = abortController const { signal } = abortController
@ -18,6 +24,6 @@ const fetchWithTimeout = ({ timeout = 120000 } = {}) => {
throw e throw e
} }
} }
} })
export default fetchWithTimeout export default getFetchWithTimeout

View File

@ -2,6 +2,7 @@ import assert from 'assert'
import freeze from 'deep-freeze-strict' import freeze from 'deep-freeze-strict'
import reducers from '../../../ui/app/ducks' import reducers from '../../../ui/app/ducks'
import * as actionConstants from '../../../ui/app/store/actionConstants' import * as actionConstants from '../../../ui/app/store/actionConstants'
import { NETWORK_TYPE_RPC } from '../../../shared/constants/network'
describe('config view actions', function () { describe('config view actions', function () {
const initialState = { const initialState = {
@ -25,7 +26,7 @@ describe('config view actions', function () {
} }
const result = reducers(initialState, action) const result = reducers(initialState, action)
assert.equal(result.metamask.provider.type, 'rpc') assert.equal(result.metamask.provider.type, NETWORK_TYPE_RPC)
assert.equal(result.metamask.provider.rpcUrl, 'foo') assert.equal(result.metamask.provider.rpcUrl, 'foo')
}) })
}) })

View File

@ -7,10 +7,7 @@ import BigNumber from 'bignumber.js'
import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens' import DetectTokensController from '../../../../app/scripts/controllers/detect-tokens'
import NetworkController from '../../../../app/scripts/controllers/network/network' import NetworkController from '../../../../app/scripts/controllers/network/network'
import PreferencesController from '../../../../app/scripts/controllers/preferences' import PreferencesController from '../../../../app/scripts/controllers/preferences'
import { import { MAINNET, ROPSTEN } from '../../../../shared/constants/network'
MAINNET,
ROPSTEN,
} from '../../../../app/scripts/controllers/network/enums'
describe('DetectTokensController', function () { describe('DetectTokensController', function () {
const sandbox = sinon.createSandbox() const sandbox = sinon.createSandbox()

View File

@ -14,7 +14,7 @@ import {
ROPSTEN, ROPSTEN,
ROPSTEN_CHAIN_ID, ROPSTEN_CHAIN_ID,
ROPSTEN_NETWORK_ID, ROPSTEN_NETWORK_ID,
} from '../../../../app/scripts/controllers/network/enums' } from '../../../../shared/constants/network'
import { import {
TRANSACTION_CATEGORIES, TRANSACTION_CATEGORIES,
TRANSACTION_STATUSES, TRANSACTION_STATUSES,

View File

@ -1,7 +1,7 @@
import { strict as assert } from 'assert' import { strict as assert } from 'assert'
import sinon from 'sinon' import sinon from 'sinon'
import MetaMetricsController from '../../../../app/scripts/controllers/metametrics' import MetaMetricsController from '../../../../app/scripts/controllers/metametrics'
import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../../shared/constants/app'
import { createSegmentMock } from '../../../../app/scripts/lib/segment' import { createSegmentMock } from '../../../../app/scripts/lib/segment'
import { import {
METAMETRICS_ANONYMOUS_ID, METAMETRICS_ANONYMOUS_ID,

View File

@ -5,8 +5,8 @@ import { ApprovalController } from '@metamask/controllers'
import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods' import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'
import { CAVEAT_NAMES } from '../../../../../shared/constants/permissions'
import { import {
CAVEAT_NAMES,
CAVEAT_TYPES, CAVEAT_TYPES,
NOTIFICATION_NAMES, NOTIFICATION_NAMES,
} from '../../../../../app/scripts/controllers/permissions/enums' } from '../../../../../app/scripts/controllers/permissions/enums'

View File

@ -8,7 +8,7 @@ import { ObservableStore } from '@metamask/obs-store'
import { import {
ROPSTEN_NETWORK_ID, ROPSTEN_NETWORK_ID,
MAINNET_NETWORK_ID, MAINNET_NETWORK_ID,
} from '../../../../app/scripts/controllers/network/enums' } from '../../../../shared/constants/network'
import { ETH_SWAPS_TOKEN_ADDRESS } from '../../../../ui/app/helpers/constants/swaps' import { ETH_SWAPS_TOKEN_ADDRESS } from '../../../../ui/app/helpers/constants/swaps'
import { createTestProviderTools } from '../../../stub/provider' import { createTestProviderTools } from '../../../stub/provider'
import SwapsController, { import SwapsController, {

View File

@ -1,14 +1,16 @@
import assert from 'assert' import assert from 'assert'
import nock from 'nock' import nock from 'nock'
import fetchWithTimeout from '../../../app/scripts/lib/fetch-with-timeout' import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'
describe('fetchWithTimeout', function () { describe('getFetchWithTimeout', function () {
it('fetches a url', async function () { it('fetches a url', async function () {
nock('https://api.infura.io').get('/money').reply(200, '{"hodl": false}') nock('https://api.infura.io').get('/money').reply(200, '{"hodl": false}')
const fetch = fetchWithTimeout() const fetchWithTimeout = getFetchWithTimeout(30000)
const response = await (await fetch('https://api.infura.io/money')).json() const response = await (
await fetchWithTimeout('https://api.infura.io/money')
).json()
assert.deepEqual(response, { assert.deepEqual(response, {
hodl: false, hodl: false,
}) })
@ -20,12 +22,10 @@ describe('fetchWithTimeout', function () {
.delay(2000) .delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}') .reply(200, '{"moon": "2012-12-21T11:11:11Z"}')
const fetch = fetchWithTimeout({ const fetchWithTimeout = getFetchWithTimeout(123)
timeout: 123,
})
try { try {
await fetch('https://api.infura.io/moon').then((r) => r.json()) await fetchWithTimeout('https://api.infura.io/moon').then((r) => r.json())
assert.fail('Request should throw') assert.fail('Request should throw')
} catch (e) { } catch (e) {
assert.ok(e) assert.ok(e)
@ -38,15 +38,20 @@ describe('fetchWithTimeout', function () {
.delay(2000) .delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}') .reply(200, '{"moon": "2012-12-21T11:11:11Z"}')
const fetch = fetchWithTimeout({ const fetchWithTimeout = getFetchWithTimeout(123)
timeout: 123,
})
try { try {
await fetch('https://api.infura.io/moon').then((r) => r.json()) await fetchWithTimeout('https://api.infura.io/moon').then((r) => r.json())
assert.fail('Request should be aborted') assert.fail('Request should be aborted')
} catch (e) { } catch (e) {
assert.deepEqual(e.message, 'Aborted') assert.deepEqual(e.message, 'Aborted')
} }
}) })
it('throws on invalid timeout', async function () {
assert.throws(() => getFetchWithTimeout(), 'should throw')
assert.throws(() => getFetchWithTimeout(-1), 'should throw')
assert.throws(() => getFetchWithTimeout({}), 'should throw')
assert.throws(() => getFetchWithTimeout(true), 'should throw')
})
}) })

View File

@ -10,7 +10,7 @@ import {
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_BACKGROUND, ENVIRONMENT_TYPE_BACKGROUND,
} from '../../../app/scripts/lib/enums' } from '../../../shared/constants/app'
describe('app utils', function () { describe('app utils', function () {
describe('getEnvironmentType', function () { describe('getEnvironmentType', function () {

View File

@ -1,3 +1,5 @@
import { NETWORK_TYPE_RPC } from '../../shared/constants/network'
/** /**
* @typedef {Object} FirstTimeState * @typedef {Object} FirstTimeState
* @property {Object} config Initial configuration parameters * @property {Object} config Initial configuration parameters
@ -11,7 +13,7 @@ const initialState = {
config: {}, config: {},
NetworkController: { NetworkController: {
provider: { provider: {
type: 'rpc', type: NETWORK_TYPE_RPC,
rpcUrl: 'http://localhost:8545', rpcUrl: 'http://localhost:8545',
chainId: '0x539', chainId: '0x539',
}, },

View File

@ -3,7 +3,7 @@ import migration51 from '../../../app/scripts/migrations/051'
import { import {
INFURA_PROVIDER_TYPES, INFURA_PROVIDER_TYPES,
NETWORK_TYPE_TO_ID_MAP, NETWORK_TYPE_TO_ID_MAP,
} from '../../../app/scripts/controllers/network/enums' } from '../../../shared/constants/network'
describe('migration #51', function () { describe('migration #51', function () {
it('should update the version metadata', async function () { it('should update the version metadata', async function () {

View File

@ -4,7 +4,7 @@ import { debounce } from 'lodash'
import Fuse from 'fuse.js' import Fuse from 'fuse.js'
import InputAdornment from '@material-ui/core/InputAdornment' import InputAdornment from '@material-ui/core/InputAdornment'
import classnames from 'classnames' import classnames from 'classnames'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import Identicon from '../../ui/identicon' import Identicon from '../../ui/identicon'
import SiteIcon from '../../ui/site-icon' import SiteIcon from '../../ui/site-icon'

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { import {
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
} from '../../../../../../app/scripts/lib/enums' } from '../../../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'
import NetworkDisplay from '../../network-display' import NetworkDisplay from '../../network-display'
import Identicon from '../../../ui/identicon' import Identicon from '../../../ui/identicon'

View File

@ -9,7 +9,8 @@ import {
NETWORKS_ROUTE, NETWORKS_ROUTE,
NETWORKS_FORM_ROUTE, NETWORKS_FORM_ROUTE,
} from '../../../helpers/constants/routes' } from '../../../helpers/constants/routes'
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
import { import {
getEnvironmentType, getEnvironmentType,
isPrefixedFormattedHexString, isPrefixedFormattedHexString,
@ -117,7 +118,7 @@ class NetworkDropdown extends Component {
return reversedRpcListDetail.map((entry) => { return reversedRpcListDetail.map((entry) => {
const { rpcUrl, chainId, ticker = 'ETH', nickname = '' } = entry const { rpcUrl, chainId, ticker = 'ETH', nickname = '' } = entry
const isCurrentRpcTarget = const isCurrentRpcTarget =
provider.type === 'rpc' && rpcUrl === provider.rpcUrl provider.type === NETWORK_TYPE_RPC && rpcUrl === provider.rpcUrl
return ( return (
<DropdownMenuItem <DropdownMenuItem

View File

@ -1,4 +1,5 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
import * as actions from '../../../store/actions' import * as actions from '../../../store/actions'
import { getNetworkIdentifier } from '../../../selectors' import { getNetworkIdentifier } from '../../../selectors'
import LoadingNetworkScreen from './loading-network-screen.component' import LoadingNetworkScreen from './loading-network-screen.component'
@ -9,7 +10,9 @@ const mapStateToProps = (state) => {
const { rpcUrl, chainId, ticker, nickname, type } = provider const { rpcUrl, chainId, ticker, nickname, type } = provider
const setProviderArgs = const setProviderArgs =
type === 'rpc' ? [rpcUrl, chainId, ticker, nickname] : [provider.type] type === NETWORK_TYPE_RPC
? [rpcUrl, chainId, ticker, nickname]
: [provider.type]
return { return {
isLoadingNetwork: network === 'loading', isLoadingNetwork: network === 'loading',

View File

@ -16,7 +16,7 @@ import {
import { useI18nContext } from '../../../hooks/useI18nContext' import { useI18nContext } from '../../../hooks/useI18nContext'
import { useMetricEvent } from '../../../hooks/useMetricEvent' import { useMetricEvent } from '../../../hooks/useMetricEvent'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'
export default function AccountOptionsMenu({ anchorElement, onClose }) { export default function AccountOptionsMenu({ anchorElement, onClose }) {
const t = useI18nContext() const t = useI18nContext()

View File

@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'
import SelectedAccount from '../selected-account' import SelectedAccount from '../selected-account'
import ConnectedStatusIndicator from '../connected-status-indicator' import ConnectedStatusIndicator from '../connected-status-indicator'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'
import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes' import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'
import { useI18nContext } from '../../../hooks/useI18nContext' import { useI18nContext } from '../../../hooks/useI18nContext'
import { useMetricEvent } from '../../../hooks/useMetricEvent' import { useMetricEvent } from '../../../hooks/useMetricEvent'

View File

@ -6,7 +6,7 @@ import * as actions from '../../../store/actions'
import { resetCustomData as resetCustomGasData } from '../../../ducks/gas/gas.duck' import { resetCustomData as resetCustomGasData } from '../../../ducks/gas/gas.duck'
import isMobileView from '../../../../lib/is-mobile-view' import isMobileView from '../../../../lib/is-mobile-view'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'
// Modal Components // Modal Components
import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container' import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container'

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import log from 'loglevel' import log from 'loglevel'
import { BrowserQRCodeReader } from '@zxing/library' import { BrowserQRCodeReader } from '@zxing/library'
import { getEnvironmentType } from '../../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../../shared/constants/app'
import Spinner from '../../../ui/spinner' import Spinner from '../../../ui/spinner'
import WebcamUtils from '../../../../../lib/webcam-utils' import WebcamUtils from '../../../../../lib/webcam-utils'
import PageContainerFooter from '../../../ui/page-container/page-container-footer/page-container-footer.component' import PageContainerFooter from '../../../ui/page-container/page-container-footer/page-container-footer.component'

View File

@ -1,21 +1,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import { import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
MAINNET_NETWORK_ID,
ROPSTEN_NETWORK_ID,
RINKEBY_NETWORK_ID,
KOVAN_NETWORK_ID,
GOERLI_NETWORK_ID,
} from '../../../../../app/scripts/controllers/network/enums'
const networkIdToTypeMap = {
[MAINNET_NETWORK_ID]: 'mainnet',
[ROPSTEN_NETWORK_ID]: 'ropsten',
[RINKEBY_NETWORK_ID]: 'rinkeby',
[GOERLI_NETWORK_ID]: 'goerli',
[KOVAN_NETWORK_ID]: 'kovan',
}
export default class NetworkDisplay extends Component { export default class NetworkDisplay extends Component {
static defaultProps = { static defaultProps = {
@ -23,9 +9,9 @@ export default class NetworkDisplay extends Component {
} }
static propTypes = { static propTypes = {
networkNickname: PropTypes.string.isRequired,
networkType: PropTypes.string.isRequired,
colored: PropTypes.bool, colored: PropTypes.bool,
network: PropTypes.string,
provider: PropTypes.object,
} }
static contextTypes = { static contextTypes = {
@ -33,12 +19,11 @@ export default class NetworkDisplay extends Component {
} }
renderNetworkIcon() { renderNetworkIcon() {
const { network } = this.props const { networkType } = this.props
const networkClass = networkIdToTypeMap[network]
return networkClass ? ( return networkType ? (
<div <div
className={`network-display__icon network-display__icon--${networkClass}`} className={`network-display__icon network-display__icon--${networkType}`}
/> />
) : ( ) : (
<div <div
@ -52,24 +37,19 @@ export default class NetworkDisplay extends Component {
} }
render() { render() {
const { const { colored, networkNickname, networkType } = this.props
colored,
network,
provider: { type, nickname },
} = this.props
const networkClass = networkIdToTypeMap[network]
return ( return (
<div <div
className={classnames('network-display__container', { className={classnames('network-display__container', {
'network-display__container--colored': colored, 'network-display__container--colored': colored,
[`network-display__container--${networkClass}`]: [`network-display__container--${networkType}`]:
colored && networkClass, colored && networkType,
})} })}
> >
{networkClass ? ( {networkType ? (
<div <div
className={`network-display__icon network-display__icon--${networkClass}`} className={`network-display__icon network-display__icon--${networkType}`}
/> />
) : ( ) : (
<div <div
@ -81,7 +61,9 @@ export default class NetworkDisplay extends Component {
/> />
)} )}
<div className="network-display__name"> <div className="network-display__name">
{type === 'rpc' && nickname ? nickname : this.context.t(type)} {networkType === NETWORK_TYPE_RPC && networkNickname
? networkNickname
: this.context.t(networkType)}
</div> </div>
</div> </div>
) )

View File

@ -1,10 +1,14 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import NetworkDisplay from './network-display.component' import NetworkDisplay from './network-display.component'
const mapStateToProps = ({ metamask: { network, provider } }) => { const mapStateToProps = ({
metamask: {
provider: { nickname, type },
},
}) => {
return { return {
network, networkNickname: nickname,
provider, networkType: type,
} }
} }

View File

@ -7,7 +7,7 @@ import { ObjectInspector } from 'react-inspector'
import { import {
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
MESSAGE_TYPE, MESSAGE_TYPE,
} from '../../../../../app/scripts/lib/enums' } from '../../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import Identicon from '../../ui/identicon' import Identicon from '../../ui/identicon'
import AccountListItem from '../account-list-item' import AccountListItem from '../account-list-item'

View File

@ -2,7 +2,7 @@ import { connect } from 'react-redux'
import { compose } from 'redux' import { compose } from 'redux'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { MESSAGE_TYPE } from '../../../../../app/scripts/lib/enums' import { MESSAGE_TYPE } from '../../../../../shared/constants/app'
import { goHome } from '../../../store/actions' import { goHome } from '../../../store/actions'
import { import {
accountsWithSendEtherInfoSelector, accountsWithSendEtherInfoSelector,

View File

@ -1,3 +1,3 @@
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../../shared/constants/app'
export { ENVIRONMENT_TYPE_NOTIFICATION } export { ENVIRONMENT_TYPE_NOTIFICATION }

View File

@ -2,7 +2,7 @@ import { connect } from 'react-redux'
import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck' import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'
import { accountsWithSendEtherInfoSelector } from '../../../selectors' import { accountsWithSendEtherInfoSelector } from '../../../selectors'
import { getAccountByAddress } from '../../../helpers/utils/util' import { getAccountByAddress } from '../../../helpers/utils/util'
import { MESSAGE_TYPE } from '../../../../../app/scripts/lib/enums' import { MESSAGE_TYPE } from '../../../../../shared/constants/app'
import SignatureRequest from './signature-request.component' import SignatureRequest from './signature-request.component'
function mapStateToProps(state) { function mapStateToProps(state) {

View File

@ -34,7 +34,7 @@ import {
setSwapsFromToken, setSwapsFromToken,
} from '../../../ducks/swaps/swaps' } from '../../../ducks/swaps/swaps'
import IconButton from '../../ui/icon-button' import IconButton from '../../ui/icon-button'
import { MAINNET_CHAIN_ID } from '../../../../../app/scripts/controllers/network/enums' import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network'
import WalletOverview from './wallet-overview' import WalletOverview from './wallet-overview'
const EthOverview = ({ className }) => { const EthOverview = ({ className }) => {

View File

@ -27,7 +27,7 @@ import {
getCurrentKeyring, getCurrentKeyring,
getCurrentChainId, getCurrentChainId,
} from '../../../selectors/selectors' } from '../../../selectors/selectors'
import { MAINNET_CHAIN_ID } from '../../../../../app/scripts/controllers/network/enums' import { MAINNET_CHAIN_ID } from '../../../../../shared/constants/network'
import SwapIcon from '../../ui/icon/swap-icon.component' import SwapIcon from '../../ui/icon/swap-icon.component'
import SendIcon from '../../ui/icon/overview-send-icon.component' import SendIcon from '../../ui/icon/overview-send-icon.component'

View File

@ -0,0 +1 @@
export { default } from './typography'

View File

@ -0,0 +1,58 @@
import React from 'react'
import classnames from 'classnames'
import PropTypes from 'prop-types'
import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'
const { H6, H7, H8, H9 } = TYPOGRAPHY
export default function Typography({
variant = TYPOGRAPHY.Paragraph,
className,
color = COLORS.BLACK,
tag,
children,
spacing = 1,
fontWeight = 'normal',
align,
}) {
const computedClassName = classnames(
'typography',
className,
`typography--${variant}`,
`typography--align-${align}`,
`typography--spacing-${spacing}`,
`typography--color-${color}`,
`typography--weight-${fontWeight}`,
)
let Tag = tag ?? variant
if (Tag === TYPOGRAPHY.Paragraph) {
Tag = 'p'
} else if ([H7, H8, H9].includes(Tag)) {
Tag = H6
}
return <Tag className={computedClassName}>{children}</Tag>
}
Typography.propTypes = {
variant: PropTypes.oneOf(Object.values(TYPOGRAPHY)),
children: PropTypes.node.isRequired,
color: PropTypes.oneOf(Object.values(COLORS)),
className: PropTypes.string,
align: PropTypes.oneOf(['center', 'right']),
spacing: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8]),
fontWeight: PropTypes.oneOf(['bold', 'normal']),
tag: PropTypes.oneOf([
'p',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'span',
'div',
]),
}

View File

@ -0,0 +1,38 @@
@use "design-system";
@use "sass:map";
.typography {
@include design-system.Paragraph;
@each $variant in map.keys(design-system.$typography-variants) {
&--#{$variant} {
@include design-system.typography($variant);
}
}
@each $variant, $color in design-system.$color-map {
&--color-#{$variant} {
color: $color;
}
}
@each $variant, $weight in design-system.$typography-font-weights {
&--weight-#{$variant} {
font-weight: $weight;
}
}
&--align-center {
text-align: center;
}
&--align-right {
text-align: right;
}
@for $i from 1 through 8 {
&--spacing-#{$i} {
margin: #{$i * 4}px auto;
}
}
}

View File

@ -0,0 +1,53 @@
import React from 'react'
import { number, select, text } from '@storybook/addon-knobs'
import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'
import Typography from '.'
export default {
title: 'Typography',
}
const fontWeightOptions = {
bold: 'bold',
normal: 'normal',
}
const alignOptions = {
left: undefined,
center: 'center',
right: 'right',
}
export const list = () => (
<div style={{ width: '80%', flexDirection: 'column' }}>
{Object.values(TYPOGRAPHY).map((variant) => (
<div key={variant} style={{ width: '100%' }}>
<Typography
variant={variant}
color={select('color', COLORS, COLORS.BLACK)}
spacing={number('spacing', 1, { range: true, min: 1, max: 8 })}
align={select('align', alignOptions, undefined)}
fontWeight={select('font weight', fontWeightOptions, 'normal')}
>
{variant}
</Typography>
</div>
))}
</div>
)
export const TheQuickOrangeFox = () => (
<div style={{ width: '80%', flexDirection: 'column' }}>
<div style={{ width: '100%' }}>
<Typography
color={select('color', COLORS, COLORS.BLACK)}
variant={select('variant', TYPOGRAPHY, TYPOGRAPHY.Paragraph)}
spacing={number('spacing', 1, { range: true, min: 1, max: 8 })}
align={select('align', alignOptions, undefined)}
fontWeight={select('font weight', fontWeightOptions, 'normal')}
>
{text('content', 'The quick orange fox jumped over the lazy dog.')}
</Typography>
</div>
</div>
)

View File

@ -37,5 +37,6 @@
@import 'toggle-button/index'; @import 'toggle-button/index';
@import 'token-balance/index'; @import 'token-balance/index';
@import 'tooltip/index'; @import 'tooltip/index';
@import 'typography/typography';
@import 'unit-input/index'; @import 'unit-input/index';
@import 'url-icon/index'; @import 'url-icon/index';

View File

@ -74,3 +74,66 @@ $accent-pink: #ff45d8;
$neutral-white: #fff; $neutral-white: #fff;
$neutral-black: $Black-100; $neutral-black: $Black-100;
$neutral-grey: $Grey-500; $neutral-grey: $Grey-500;
// Everything below this line is part of the new color system
$primary-1: #037dd6;
$primary-2: #eaf6ff;
$primary-3: #0260a4;
$secondary-1: #f66a0a;
$secondary-2: #fef5ef;
$secondary-3: #c65507;
$error-1: #d73a49;
$error-2: #fcf2f3;
$error-3: #b92534;
$alert-1: #ffd33d;
$alert-2: #fefcde;
$alert-3: #f8c000;
$success-1: #4cd964;
$success-2: #caf4d1;
$success-3: #219e37;
$ui-black: #24292e;
$ui-white: #fff;
$ui-1: #f2f3f4;
$ui-2: #d6d9dc;
$ui-3: #bbc0c5;
$ui-4: #6a737d;
$mainnet: #29b6af;
$ropsten: #ff4a8d;
$kovan: #9064ff;
$rinkeby: #f6c343;
$goerli: #3099f2;
$color-map: (
'ui-1': $ui-1,
'ui-2': $ui-2,
'ui-3': $ui-3,
'ui-4': $ui-4,
'white': $ui-white,
'black': $ui-black,
'primary-1': $primary-1,
'primary-2': $primary-2,
'primary-3': $primary-3,
'secondary-1': $secondary-1,
'secondary-2': $secondary-2,
'secondary-3': $secondary-3,
'alert-1': $alert-1,
'alert-2': $alert-2,
'alert-3': $alert-3,
'error-1': $error-1,
'error-2': $error-2,
'error-3': $error-3,
'success-1': $success-1,
'success-2': $success-2,
'success-3': $success-3,
'mainnet': $mainnet,
'ropsten': $ropsten,
'kovan': $kovan,
'rinkeby': $rinkeby,
'goerli': $goerli,
);

View File

@ -1,5 +1,5 @@
@import 'breakpoints'; @forward 'breakpoints';
@import 'colors'; @forward 'colors';
@import 'deprecated-colors'; @forward 'deprecated-colors';
@import 'typography'; @forward 'typography';
@import 'z-index'; @forward 'z-index';

View File

@ -69,89 +69,80 @@ $fa-font-path: 'fonts/fontawesome';
$font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif;
$font-size-h1: 2.5rem; $typography-variants: (
$font-size-h2: 2rem; 'h1': 2.5rem,
$font-size-h3: 1.5rem; 'h2': 2rem,
$font-size-h4: 1.125rem; 'h3': 1.5rem,
$font-size-h5: 1rem; 'h4': 1.125rem,
$font-size-h6: 0.875rem; 'h5': 1rem,
$font-size-paragraph: 1rem; 'h6': 0.875rem,
$font-size-h7: 0.75rem; 'paragraph': 1rem,
$font-size-h8: 0.625rem; 'h7': 0.75rem,
$font-size-h9: 0.5rem; 'h8': 0.625rem,
'h9': 0.5rem,
);
$typography-font-weights: (
'bold': 700,
'normal': 400,
);
$font-size-h1: map-get($typography-variants, 'h1');
$font-size-h2: map-get($typography-variants, 'h2');
$font-size-h3: map-get($typography-variants, 'h3');
$font-size-h4: map-get($typography-variants, 'h4');
$font-size-h5: map-get($typography-variants, 'h5');
$font-size-h6: map-get($typography-variants, 'h6');
$font-size-paragraph: map-get($typography-variants, 'paragraph');
$font-size-h7: map-get($typography-variants, 'h7');
$font-size-h8: map-get($typography-variants, 'h8');
$font-size-h9: map-get($typography-variants, 'h9');
@mixin typography($variant) {
font-size: map-get($typography-variants, $variant);
font-family: $font-family;
line-height: 140%;
font-style: normal;
font-weight: normal;
}
// Typography // Typography
@mixin H1 { @mixin H1 {
font-style: normal; @include typography('h1');
font-weight: normal;
font-size: $font-size-h1;
font-family: $font-family;
line-height: 140%;
} }
@mixin H2 { @mixin H2 {
font-style: normal; @include typography('h2');
font-weight: normal;
font-size: $font-size-h2;
font-family: $font-family;
line-height: 140%;
} }
@mixin H3 { @mixin H3 {
font-style: normal; @include typography('h3');
font-weight: normal;
font-size: $font-size-h3;
font-family: $font-family;
line-height: 140%;
} }
@mixin H4 { @mixin H4 {
font-style: normal; @include typography('h4');
font-weight: normal;
font-size: $font-size-h4;
font-family: $font-family;
line-height: 140%;
} }
@mixin H5 { @mixin H5 {
font-style: normal; @include typography('h5');
font-weight: normal;
font-size: $font-size-h5;
line-height: 140%;
} }
@mixin H6 { @mixin H6 {
font-style: normal; @include typography('h6');
font-weight: normal;
font-size: $font-size-h6; // 14px @default
line-height: 140%;
} }
@mixin Paragraph { @mixin Paragraph {
font-style: normal; @include typography('paragraph');
font-weight: normal;
font-size: $font-size-paragraph;
line-height: 140%;
} }
@mixin H7 { @mixin H7 {
font-style: normal; @include typography('h7');
font-weight: normal;
font-size: $font-size-h7;
line-height: 140%;
} }
@mixin H8 { @mixin H8 {
font-style: normal; @include typography('h8');
font-weight: normal;
font-size: $font-size-h8;
line-height: 140%;
} }
@mixin H9 { @mixin H9 {
font-style: normal; @include typography('h9');
font-weight: normal;
font-size: $font-size-h9;
line-height: 140%;
} }

View File

@ -1,8 +1,10 @@
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util' import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util'
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
const fetchWithTimeout = getFetchWithTimeout(30000)
// Actions // Actions
const BASIC_GAS_ESTIMATE_LOADING_FINISHED = const BASIC_GAS_ESTIMATE_LOADING_FINISHED =
@ -97,7 +99,7 @@ export function basicGasEstimatesLoadingFinished() {
async function basicGasPriceQuery() { async function basicGasPriceQuery() {
const url = `https://api.metaswap.codefi.network/gasPrices` const url = `https://api.metaswap.codefi.network/gasPrices`
return await window.fetch(url, { return await fetchWithTimeout(url, {
headers: {}, headers: {},
referrer: 'https://api.metaswap.codefi.network/gasPrices', referrer: 'https://api.metaswap.codefi.network/gasPrices',
referrerPolicy: 'no-referrer-when-downgrade', referrerPolicy: 'no-referrer-when-downgrade',

View File

@ -1,5 +1,6 @@
import * as actionConstants from '../../store/actionConstants' import * as actionConstants from '../../store/actionConstants'
import { ALERT_TYPES } from '../../../../shared/constants/alerts' import { ALERT_TYPES } from '../../../../shared/constants/alerts'
import { NETWORK_TYPE_RPC } from '../../../../shared/constants/network'
export default function reduceMetamask(state = {}, action) { export default function reduceMetamask(state = {}, action) {
const metamaskState = { const metamaskState = {
@ -63,7 +64,7 @@ export default function reduceMetamask(state = {}, action) {
return { return {
...metamaskState, ...metamaskState,
provider: { provider: {
type: 'rpc', type: NETWORK_TYPE_RPC,
rpcUrl: action.value, rpcUrl: action.value,
}, },
} }

View File

@ -5,14 +5,6 @@ export const WEI = 'WEI'
export const PRIMARY = 'PRIMARY' export const PRIMARY = 'PRIMARY'
export const SECONDARY = 'SECONDARY' export const SECONDARY = 'SECONDARY'
export const NETWORK_TYPES = {
KOVAN: 'kovan',
MAINNET: 'mainnet',
RINKEBY: 'rinkeby',
ROPSTEN: 'ropsten',
GOERLI: 'goerli',
}
export const GAS_ESTIMATE_TYPES = { export const GAS_ESTIMATE_TYPES = {
SLOW: 'SLOW', SLOW: 'SLOW',
AVERAGE: 'AVERAGE', AVERAGE: 'AVERAGE',

View File

@ -0,0 +1,41 @@
export const COLORS = {
UI1: 'ui-1',
UI2: 'ui-2',
UI3: 'ui-3',
UI4: 'ui-4',
BLACK: 'black',
WHITE: 'white',
PRIMARY1: 'primary-1',
PRIMARY2: 'primary-2',
PRIMARY3: 'primary-3',
SECONDARY1: 'secondary-1',
SECONDARY2: 'secondary-2',
SECONDARY3: 'secondary-3',
SUCCESS1: 'success-1',
SUCCESS2: 'success-2',
SUCCESS3: 'success-3',
ERROR1: 'error1',
ERROR2: 'error2',
ERROR3: 'error3',
ALERT1: 'alert-1',
ALERT2: 'alert-2',
ALERT3: 'alert-3',
MAINNET: 'mainnet',
ROPSTEN: 'ropsten',
KOVAN: 'kovan',
RINKEBY: 'rinkeby',
GOERLI: 'goerli',
}
export const TYPOGRAPHY = {
H1: 'h1',
H2: 'h2',
H3: 'h3',
H4: 'h4',
H5: 'h5',
H6: 'h6',
H7: 'h7',
H8: 'h8',
H9: 'h9',
Paragraph: 'paragraph',
}

View File

@ -1,5 +1,5 @@
import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers' import { getStorageItem, setStorageItem } from '../../../lib/storage-helpers'
import fetchWithTimeout from '../../../../app/scripts/lib/fetch-with-timeout' import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
const fetchWithCache = async ( const fetchWithCache = async (
url, url,
@ -29,8 +29,8 @@ const fetchWithCache = async (
return cachedResponse return cachedResponse
} }
fetchOptions.headers.set('Content-Type', 'application/json') fetchOptions.headers.set('Content-Type', 'application/json')
const _fetch = timeout ? fetchWithTimeout({ timeout }) : window.fetch const fetchWithTimeout = getFetchWithTimeout(timeout)
const response = await _fetch(url, { const response = await fetchWithTimeout(url, {
referrerPolicy: 'no-referrer-when-downgrade', referrerPolicy: 'no-referrer-when-downgrade',
body: null, body: null,
method: 'GET', method: 'GET',

View File

@ -1,9 +1,12 @@
// cross-browser connection to extension i18n API // cross-browser connection to extension i18n API
import React from 'react' import React from 'react'
import log from 'loglevel' import log from 'loglevel'
import * as Sentry from '@sentry/browser' import * as Sentry from '@sentry/browser'
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
const fetchWithTimeout = getFetchWithTimeout(30000)
const warned = {} const warned = {}
const missingMessageErrors = {} const missingMessageErrors = {}
const missingSubstitutionErrors = {} const missingSubstitutionErrors = {}
@ -95,7 +98,7 @@ export const getMessage = (localeCode, localeMessages, key, substitutions) => {
export async function fetchLocale(localeCode) { export async function fetchLocale(localeCode) {
try { try {
const response = await window.fetch( const response = await fetchWithTimeout(
`./_locales/${localeCode}/messages.json`, `./_locales/${localeCode}/messages.json`,
) )
return await response.json() return await response.json()
@ -120,7 +123,7 @@ export async function loadRelativeTimeFormatLocaleData(localeCode) {
} }
async function fetchRelativeTimeFormatData(languageTag) { async function fetchRelativeTimeFormatData(languageTag) {
const response = await window.fetch( const response = await fetchWithTimeout(
`./intl/${languageTag}/relative-time-format-data.json`, `./intl/${languageTag}/relative-time-format-data.json`,
) )
return await response.json() return await response.json()

View File

@ -4,6 +4,9 @@ import BigNumber from 'bignumber.js'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { addHexPrefix } from '../../../../app/scripts/lib/util' import { addHexPrefix } from '../../../../app/scripts/lib/util'
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
const fetchWithTimeout = getFetchWithTimeout(30000)
// formatData :: ( date: <Unix Timestamp> ) -> String // formatData :: ( date: <Unix Timestamp> ) -> String
export function formatDate(date, format = "M/d/y 'at' T") { export function formatDate(date, format = "M/d/y 'at' T") {
@ -478,19 +481,17 @@ export async function jsonRpcRequest(rpcUrl, rpcMethod, rpcParams = []) {
headers.Authorization = `Basic ${encodedAuth}` headers.Authorization = `Basic ${encodedAuth}`
fetchUrl = `${origin}${pathname}${search}` fetchUrl = `${origin}${pathname}${search}`
} }
const jsonRpcResponse = await window const jsonRpcResponse = await fetchWithTimeout(fetchUrl, {
.fetch(fetchUrl, { method: 'POST',
method: 'POST', body: JSON.stringify({
body: JSON.stringify({ id: Date.now().toString(),
id: Date.now().toString(), jsonrpc: '2.0',
jsonrpc: '2.0', method: rpcMethod,
method: rpcMethod, params: rpcParams,
params: rpcParams, }),
}), headers,
headers, cache: 'default',
cache: 'default', }).then((httpResponse) => httpResponse.json())
})
.then((httpResponse) => httpResponse.json())
if ( if (
!jsonRpcResponse || !jsonRpcResponse ||

View File

@ -4,7 +4,7 @@ import Button from '../../components/ui/button'
import Identicon from '../../components/ui/identicon' import Identicon from '../../components/ui/identicon'
import TokenBalance from '../../components/ui/token-balance' import TokenBalance from '../../components/ui/token-balance'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'
export default class ConfirmAddSuggestedToken extends Component { export default class ConfirmAddSuggestedToken extends Component {
static contextTypes = { static contextTypes = {

View File

@ -9,7 +9,7 @@ import Identicon from '../../components/ui/identicon'
import Tooltip from '../../components/ui/tooltip' import Tooltip from '../../components/ui/tooltip'
import Copy from '../../components/ui/icon/copy-icon.component' import Copy from '../../components/ui/icon/copy-icon.component'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { conversionUtil } from '../../helpers/utils/conversion-util' import { conversionUtil } from '../../helpers/utils/conversion-util'

View File

@ -5,7 +5,7 @@ import AccountListItem from '../../components/app/account-list-item'
import Button from '../../components/ui/button' import Button from '../../components/ui/button'
import Identicon from '../../components/ui/identicon' import Identicon from '../../components/ui/identicon'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { conversionUtil } from '../../helpers/utils/conversion-util' import { conversionUtil } from '../../helpers/utils/conversion-util'

View File

@ -1,7 +1,7 @@
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import ConfirmPageContainer, { import ConfirmPageContainer, {
ConfirmDetailRow, ConfirmDetailRow,

View File

@ -14,7 +14,7 @@ import {
DECRYPT_MESSAGE_REQUEST_PATH, DECRYPT_MESSAGE_REQUEST_PATH,
ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, ENCRYPTION_PUBLIC_KEY_REQUEST_PATH,
} from '../../helpers/constants/routes' } from '../../helpers/constants/routes'
import { MESSAGE_TYPE } from '../../../../app/scripts/lib/enums' import { MESSAGE_TYPE } from '../../../../shared/constants/app'
import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction' import { TRANSACTION_CATEGORIES } from '../../../../shared/constants/transaction'
export default class ConfirmTransactionSwitch extends Component { export default class ConfirmTransactionSwitch extends Component {

View File

@ -10,7 +10,7 @@ import SignatureRequest from '../../components/app/signature-request'
import SignatureRequestOriginal from '../../components/app/signature-request-original' import SignatureRequestOriginal from '../../components/app/signature-request-original'
import Loading from '../../components/ui/loading-screen' import Loading from '../../components/ui/loading-screen'
import { getMostRecentOverviewPage } from '../../ducks/history/history' import { getMostRecentOverviewPage } from '../../ducks/history/history'
import { MESSAGE_TYPE } from '../../../../app/scripts/lib/enums' import { MESSAGE_TYPE } from '../../../../shared/constants/app'
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'
function mapStateToProps(state) { function mapStateToProps(state) {

View File

@ -90,7 +90,7 @@ class AccountList extends Component {
name="selectedAccount" name="selectedAccount"
id={`address-${idx}`} id={`address-${idx}`}
value={account.index} value={account.index}
onChange={(e) => this.props.onAccountChange(e.target.value)} onClick={(e) => this.props.onAccountChange(e.target.value)}
checked={ checked={
this.props.selectedAccount === account.index.toString() this.props.selectedAccount === account.index.toString()
} }

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'
class ErrorPage extends PureComponent { class ErrorPage extends PureComponent {
static contextTypes = { static contextTypes = {

View File

@ -33,7 +33,7 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { import {
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
} from '../../../../app/scripts/lib/enums' } from '../../../../shared/constants/app'
import { import {
ALERT_TYPES, ALERT_TYPES,
WEB3_SHIM_USAGE_ALERT_STATES, WEB3_SHIM_USAGE_ALERT_STATES,

View File

@ -2,7 +2,7 @@ import PropTypes from 'prop-types'
import React, { Component } from 'react' import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom' import { Switch, Route } from 'react-router-dom'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app'
import { DEFAULT_ROUTE } from '../../helpers/constants/routes' import { DEFAULT_ROUTE } from '../../helpers/constants/routes'
import PermissionPageContainer from '../../components/app/permission-page-container' import PermissionPageContainer from '../../components/app/permission-page-container'
import ChooseAccount from './choose-account' import ChooseAccount from './choose-account'

View File

@ -58,7 +58,7 @@ import {
import { import {
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
} from '../../../../app/scripts/lib/enums' } from '../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction' import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction'

View File

@ -13,7 +13,7 @@ import {
isValidAddress, isValidAddress,
isValidAddressHead, isValidAddressHead,
} from '../../../../helpers/utils/util' } from '../../../../helpers/utils/util'
import { MAINNET_NETWORK_ID } from '../../../../../../app/scripts/controllers/network/enums' import { MAINNET_NETWORK_ID } from '../../../../../../shared/constants/network'
// Local Constants // Local Constants
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'

View File

@ -2,7 +2,7 @@ import { compose } from 'redux'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { getAddressBook } from '../../../selectors' import { getAddressBook } from '../../../selectors'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import { import {

View File

@ -6,7 +6,10 @@
&__logo { &__logo {
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 50%;
display: block;
margin-left: auto;
margin-right: auto;
} }
&__item { &__item {

View File

@ -95,13 +95,6 @@ export default class InfoTab extends PureComponent {
<div className="settings-page__body"> <div className="settings-page__body">
<div className="settings-page__content-row"> <div className="settings-page__content-row">
<div className="settings-page__content-item settings-page__content-item--without-height"> <div className="settings-page__content-item settings-page__content-item--without-height">
<div className="info-tab__logo-wrapper">
<img
src="images/info-logo.png"
className="info-tab__logo"
alt=""
/>
</div>
<div className="info-tab__item"> <div className="info-tab__item">
<div className="info-tab__version-header"> <div className="info-tab__version-header">
{t('metamaskVersion')} {t('metamaskVersion')}
@ -116,6 +109,9 @@ export default class InfoTab extends PureComponent {
</div> </div>
{this.renderInfoLinks()} {this.renderInfoLinks()}
</div> </div>
<div className="info-tab__logo-wrapper">
<img src="images/info-logo.png" className="info-tab__logo" alt="" />
</div>
</div> </div>
) )
} }

View File

@ -1,6 +1,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
import Button from '../../../components/ui/button' import Button from '../../../components/ui/button'
import LockIcon from '../../../components/ui/lock-icon' import LockIcon from '../../../components/ui/lock-icon'
import { import {
@ -90,7 +91,7 @@ export default class NetworksTab extends PureComponent {
const listItemNetworkIsSelected = selectRpcUrl && selectRpcUrl === rpcUrl const listItemNetworkIsSelected = selectRpcUrl && selectRpcUrl === rpcUrl
const listItemUrlIsProviderUrl = rpcUrl === providerUrl const listItemUrlIsProviderUrl = rpcUrl === providerUrl
const listItemTypeIsProviderNonRpcType = const listItemTypeIsProviderNonRpcType =
providerType !== 'rpc' && currentProviderType === providerType providerType !== NETWORK_TYPE_RPC && currentProviderType === providerType
const listItemNetworkIsCurrentProvider = const listItemNetworkIsCurrentProvider =
!networkIsSelected && !networkIsSelected &&
!networksTabIsInAddMode && !networksTabIsInAddMode &&
@ -118,12 +119,12 @@ export default class NetworksTab extends PureComponent {
className={classnames('networks-tab__networks-list-name', { className={classnames('networks-tab__networks-list-name', {
'networks-tab__networks-list-name--selected': displayNetworkListItemAsSelected, 'networks-tab__networks-list-name--selected': displayNetworkListItemAsSelected,
'networks-tab__networks-list-name--disabled': 'networks-tab__networks-list-name--disabled':
currentProviderType !== 'rpc' && currentProviderType !== NETWORK_TYPE_RPC &&
!displayNetworkListItemAsSelected, !displayNetworkListItemAsSelected,
})} })}
> >
{label || this.context.t(labelKey)} {label || this.context.t(labelKey)}
{currentProviderType !== 'rpc' && ( {currentProviderType !== NETWORK_TYPE_RPC && (
<LockIcon width="14px" height="17px" fill="#cdcdcd" /> <LockIcon width="14px" height="17px" fill="#cdcdcd" />
)} )}
</div> </div>

View File

@ -9,7 +9,7 @@ import {
RINKEBY_CHAIN_ID, RINKEBY_CHAIN_ID,
ROPSTEN, ROPSTEN,
ROPSTEN_CHAIN_ID, ROPSTEN_CHAIN_ID,
} from '../../../../../app/scripts/controllers/network/enums' } from '../../../../../shared/constants/network'
const defaultNetworksData = [ const defaultNetworksData = [
{ {

View File

@ -10,7 +10,8 @@ import {
showModal, showModal,
} from '../../../store/actions' } from '../../../store/actions'
import { NETWORKS_FORM_ROUTE } from '../../../helpers/constants/routes' import { NETWORKS_FORM_ROUTE } from '../../../helpers/constants/routes'
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../../shared/constants/app'
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
import { getEnvironmentType } from '../../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
import NetworksTab from './networks-tab.component' import NetworksTab from './networks-tab.component'
import { defaultNetworksData } from './networks-tab.constants' import { defaultNetworksData } from './networks-tab.constants'
@ -37,7 +38,7 @@ const mapStateToProps = (state, ownProps) => {
return { return {
label: rpc.nickname, label: rpc.nickname,
iconColor: '#6A737D', iconColor: '#6A737D',
providerType: 'rpc', providerType: NETWORK_TYPE_RPC,
rpcUrl: rpc.rpcUrl, rpcUrl: rpc.rpcUrl,
chainId: rpc.chainId, chainId: rpc.chainId,
ticker: rpc.ticker, ticker: rpc.ticker,
@ -61,7 +62,7 @@ const mapStateToProps = (state, ownProps) => {
networksToRender.find((network) => { networksToRender.find((network) => {
return ( return (
network.rpcUrl === provider.rpcUrl || network.rpcUrl === provider.rpcUrl ||
(network.providerType !== 'rpc' && (network.providerType !== NETWORK_TYPE_RPC &&
network.providerType === provider.type) network.providerType === provider.type)
) )
}) || {} }) || {}

View File

@ -3,7 +3,7 @@ import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { getAddressBookEntryName } from '../../selectors' import { getAddressBookEntryName } from '../../selectors'
import { isValidAddress } from '../../helpers/utils/util' import { isValidAddress } from '../../helpers/utils/util'
import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums' import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'
import { getEnvironmentType } from '../../../../app/scripts/lib/util' import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { getMostRecentOverviewPage } from '../../ducks/history/history' import { getMostRecentOverviewPage } from '../../ducks/history/history'

View File

@ -48,7 +48,7 @@ import {
SWAP_FAILED_ERROR, SWAP_FAILED_ERROR,
OFFLINE_FOR_MAINTENANCE, OFFLINE_FOR_MAINTENANCE,
} from '../../helpers/constants/swaps' } from '../../helpers/constants/swaps'
import { MAINNET_CHAIN_ID } from '../../../../app/scripts/controllers/network/enums' import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'
import { import {
resetBackgroundSwapsState, resetBackgroundSwapsState,

View File

@ -467,11 +467,11 @@ export function quotesToRenderableData(
} = quote } = quote
const sourceValue = calcTokenAmount( const sourceValue = calcTokenAmount(
sourceAmount, sourceAmount,
sourceTokenInfo.decimals || 18, sourceTokenInfo.decimals,
).toString(10) ).toString(10)
const destinationValue = calcTokenAmount( const destinationValue = calcTokenAmount(
destinationAmount, destinationAmount,
destinationTokenInfo.decimals || 18, destinationTokenInfo.decimals,
).toPrecision(8) ).toPrecision(8)
const { const {
@ -501,14 +501,11 @@ export function quotesToRenderableData(
destinationTokenInfo.symbol === 'ETH' destinationTokenInfo.symbol === 'ETH'
? calcTokenAmount( ? calcTokenAmount(
destinationAmount, destinationAmount,
destinationTokenInfo.decimals || 18, destinationTokenInfo.decimals,
).minus(rawEthFee, 10) ).minus(rawEthFee, 10)
: new BigNumber(tokenConversionRate || 0, 10) : new BigNumber(tokenConversionRate || 0, 10)
.times( .times(
calcTokenAmount( calcTokenAmount(destinationAmount, destinationTokenInfo.decimals),
destinationAmount,
destinationTokenInfo.decimals || 18,
),
10, 10,
) )
.minus(rawEthFee, 10) .minus(rawEthFee, 10)

Some files were not shown because too many files have changed in this diff Show More