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

* origin/develop: (29 commits)
  Reset swaps routeState in navigateBackToBuildQuote (#10166)
  Fix decrypt message confirmation UI crash (#10252)
  Fix site metadata JSON-RPC handler (#10243)
  Fix design system error constants (#10246)
  Remove unused environment variables (#10234)
  Update `yarn.lock` (#10241)
  Update postMessage structure for TrezorConnect 8 (#10192)
  Increase minimum Firefox version to v68 (#10195)
  Bump socket.io from 2.2.0 to 2.4.1 (#10232)
  Update `@reduxjs/toolkit` from v1.3.2 to v1.5.0 (#10228)
  eth-rpc-errors@4.0.2 (#10226)
  Add MAX_SAFE_CHAIN_ID and refactor chain ID validation (#10224)
  add chip component (#10199)
  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)
  ...
feature/default_network_editable
Mark Stacey 4 years ago
commit 74ee13f7c3
  1. 1
      .prettierignore
  2. 19
      .storybook/main.js
  3. 3
      README.md
  4. 3
      app/_locales/en/messages.json
  5. 2
      app/manifest/firefox.json
  6. 12
      app/scripts/background.js
  7. 0
      app/scripts/constants/contracts.js
  8. 5
      app/scripts/controllers/detect-tokens.js
  9. 10
      app/scripts/controllers/incoming-transactions.js
  10. 2
      app/scripts/controllers/metametrics.js
  11. 2
      app/scripts/controllers/network/createInfuraClient.js
  12. 40
      app/scripts/controllers/network/network.js
  13. 2
      app/scripts/controllers/network/util.js
  14. 5
      app/scripts/controllers/permissions/enums.js
  15. 11
      app/scripts/controllers/permissions/index.js
  16. 2
      app/scripts/controllers/permissions/permissionsLog.js
  17. 2
      app/scripts/controllers/permissions/permissionsMethodMiddleware.js
  18. 6
      app/scripts/controllers/preferences.js
  19. 5
      app/scripts/controllers/token-rates.js
  20. 2
      app/scripts/controllers/transactions/index.js
  21. 2
      app/scripts/controllers/transactions/lib/util.js
  22. 4
      app/scripts/lib/account-tracker.js
  23. 4
      app/scripts/lib/decrypt-message-manager.js
  24. 4
      app/scripts/lib/encryption-public-key-manager.js
  25. 7
      app/scripts/lib/ens-ipfs/setup.js
  26. 4
      app/scripts/lib/message-manager.js
  27. 5
      app/scripts/lib/network-store.js
  28. 4
      app/scripts/lib/personal-message-manager.js
  29. 2
      app/scripts/lib/rpc-method-middleware/handlers/get-provider-state.js
  30. 2
      app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js
  31. 2
      app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js
  32. 4
      app/scripts/lib/typed-message-manager.js
  33. 18
      app/scripts/lib/util.js
  34. 8
      app/scripts/metamask-controller.js
  35. 2
      app/scripts/migrations/051.js
  36. 2
      app/scripts/platforms/extension.js
  37. 6
      app/scripts/ui.js
  38. 2
      app/vendor/trezor/content-script.js
  39. 2
      babel.config.js
  40. 2
      development/build/scripts.js
  41. 2
      development/build/styles.js
  42. 12
      package.json
  43. 34
      shared/constants/app.js
  44. 2
      shared/constants/metametrics.js
  45. 7
      shared/constants/network.js
  46. 4
      shared/constants/permissions.js
  47. 3
      shared/modules/README.md
  48. 12
      shared/modules/fetch-with-timeout.js
  49. 30
      shared/modules/utils.js
  50. 3
      test/unit/actions/config_test.js
  51. 5
      test/unit/app/controllers/detect-tokens-test.js
  52. 2
      test/unit/app/controllers/incoming-transactions-test.js
  53. 2
      test/unit/app/controllers/metametrics-test.js
  54. 6
      test/unit/app/controllers/permissions/mocks.js
  55. 2
      test/unit/app/controllers/swaps-test.js
  56. 29
      test/unit/app/fetch-with-timeout.test.js
  57. 4
      test/unit/app/util-test.js
  58. 4
      test/unit/localhostState.js
  59. 2
      test/unit/migrations/051-test.js
  60. 2
      ui/app/components/app/account-menu/account-menu.component.js
  61. 2
      ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js
  62. 11
      ui/app/components/app/dropdowns/network-dropdown.js
  63. 5
      ui/app/components/app/loading-network-screen/loading-network-screen.container.js
  64. 2
      ui/app/components/app/menu-bar/account-options-menu.js
  65. 2
      ui/app/components/app/menu-bar/menu-bar.js
  66. 2
      ui/app/components/app/modals/modal.js
  67. 2
      ui/app/components/app/modals/qr-scanner/qr-scanner.component.js
  68. 46
      ui/app/components/app/network-display/network-display.component.js
  69. 10
      ui/app/components/app/network-display/network-display.container.js
  70. 2
      ui/app/components/app/signature-request-original/signature-request-original.component.js
  71. 2
      ui/app/components/app/signature-request-original/signature-request-original.container.js
  72. 2
      ui/app/components/app/signature-request/signature-request.constants.js
  73. 2
      ui/app/components/app/signature-request/signature-request.container.js
  74. 2
      ui/app/components/app/wallet-overview/eth-overview.js
  75. 2
      ui/app/components/app/wallet-overview/token-overview.js
  76. 55
      ui/app/components/ui/chip/chip.js
  77. 48
      ui/app/components/ui/chip/chip.scss
  78. 82
      ui/app/components/ui/chip/chip.stories.js
  79. 1
      ui/app/components/ui/chip/index.js
  80. 1
      ui/app/components/ui/typography/index.js
  81. 58
      ui/app/components/ui/typography/typography.js
  82. 38
      ui/app/components/ui/typography/typography.scss
  83. 53
      ui/app/components/ui/typography/typography.stories.js
  84. 2
      ui/app/components/ui/ui-components.scss
  85. 64
      ui/app/css/design-system/colors.scss
  86. 10
      ui/app/css/design-system/index.scss
  87. 101
      ui/app/css/design-system/typography.scss
  88. 6
      ui/app/ducks/gas/gas.duck.js
  89. 3
      ui/app/ducks/metamask/metamask.js
  90. 2
      ui/app/ducks/swaps/swaps.js
  91. 8
      ui/app/helpers/constants/common.js
  92. 42
      ui/app/helpers/constants/design-system.js
  93. 6
      ui/app/helpers/utils/fetch-with-cache.js
  94. 9
      ui/app/helpers/utils/i18n-helper.js
  95. 9
      ui/app/helpers/utils/util.js
  96. 2
      ui/app/pages/confirm-add-suggested-token/confirm-add-suggested-token.component.js
  97. 2
      ui/app/pages/confirm-decrypt-message/confirm-decrypt-message.component.js
  98. 2
      ui/app/pages/confirm-encryption-public-key/confirm-encryption-public-key.component.js
  99. 2
      ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js
  100. 2
      ui/app/pages/confirm-transaction-switch/confirm-transaction-switch.component.js
  101. Some files were not shown because too many files have changed in this diff Show More

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

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

@ -1,5 +1,8 @@
# 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).
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).

@ -845,6 +845,9 @@
"invalidBlockExplorerURL": {
"message": "Invalid Block Explorer URL"
},
"invalidChainIdTooBig": {
"message": "Invalid chain ID. The chain ID is too big."
},
"invalidCustomNetworkAlertContent1": {
"message": "The chain ID for custom network '$1' has to be re-entered.",
"description": "$1 is the name/identifier of the network."

@ -2,7 +2,7 @@
"applications": {
"gecko": {
"id": "webextension@metamask.io",
"strict_min_version": "56.0"
"strict_min_version": "68.0"
}
}
}

@ -19,6 +19,12 @@ import extension from 'extensionizer'
import { storeAsStream, storeTransformStream } from '@metamask/obs-store'
import PortStream from 'extension-port-stream'
import { captureException } from '@sentry/browser'
import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
} from '../../shared/constants/app'
import migrations from './migrations'
import Migrator from './lib/migrator'
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 getObjStructure from './lib/getObjStructure'
import setupEnsIpfsResolver from './lib/ens-ipfs/setup'
import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
} from './lib/enums'
/* eslint-enable import/first */
const { sentry } = global

@ -2,12 +2,11 @@ import Web3 from 'web3'
import contracts from '@metamask/contract-metadata'
import { warn } from 'loglevel'
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
const DEFAULT_INTERVAL = 180 * 1000
const SINGLE_CALL_BALANCES_ADDRESS =
'0xb1f8e55c7f64d203c1400b9d8555d050f94adf39'
/**
* A controller that polls for token exchange

@ -3,7 +3,7 @@ import log from 'loglevel'
import BN from 'bn.js'
import createId from '../lib/random-id'
import { bnToHex } from '../lib/util'
import fetchWithTimeout from '../lib/fetch-with-timeout'
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout'
import {
TRANSACTION_CATEGORIES,
@ -22,11 +22,9 @@ import {
RINKEBY_CHAIN_ID,
ROPSTEN,
ROPSTEN_CHAIN_ID,
} from './network/enums'
} from '../../../shared/constants/network'
const fetch = fetchWithTimeout({
timeout: 30000,
})
const fetchWithTimeout = getFetchWithTimeout(30000)
/**
* 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) {
url += `&startBlock=${parseInt(fromBlock, 10)}`
}
const response = await fetch(url)
const response = await fetchWithTimeout(url)
const parsedResponse = await response.json()
return {

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

@ -8,7 +8,7 @@ import providerFromMiddleware from 'eth-json-rpc-middleware/providerFromMiddlewa
import createInfuraMiddleware from 'eth-json-rpc-infura'
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 }) {
const infuraMiddleware = createInfuraMiddleware({

@ -9,25 +9,29 @@ import {
createEventEmitterProxy,
} from 'swappable-obj-proxy'
import EthQuery from 'eth-query'
import createMetamaskMiddleware from './createMetamaskMiddleware'
import createInfuraClient from './createInfuraClient'
import createJsonRpcClient from './createJsonRpcClient'
import {
RINKEBY,
MAINNET,
INFURA_PROVIDER_TYPES,
NETWORK_TYPE_RPC,
NETWORK_TYPE_TO_ID_MAP,
MAINNET_CHAIN_ID,
RINKEBY_CHAIN_ID,
} from './enums'
} from '../../../../shared/constants/network'
import {
isPrefixedFormattedHexString,
isSafeChainId,
} from '../../../../shared/modules/utils'
import createMetamaskMiddleware from './createMetamaskMiddleware'
import createInfuraClient from './createInfuraClient'
import createJsonRpcClient from './createJsonRpcClient'
const env = process.env.METAMASK_ENV
let defaultProviderConfigOpts
if (process.env.IN_TEST === 'true') {
defaultProviderConfigOpts = {
type: 'rpc',
type: NETWORK_TYPE_RPC,
rpcUrl: 'http://localhost:8545',
chainId: '0x539',
nickname: 'Localhost 8545',
@ -160,8 +164,16 @@ export default class NetworkController extends EventEmitter {
}
setRpcTarget(rpcUrl, chainId, ticker = 'ETH', nickname = '', rpcPrefs) {
assert.ok(
isPrefixedFormattedHexString(chainId),
`Invalid chain ID "${chainId}": invalid hex string.`,
)
assert.ok(
isSafeChainId(parseInt(chainId, 16)),
`Invalid chain ID "${chainId}": numerical value greater than max safe value.`,
)
this.setProviderConfig({
type: 'rpc',
type: NETWORK_TYPE_RPC,
rpcUrl,
chainId,
ticker,
@ -171,14 +183,14 @@ export default class NetworkController extends EventEmitter {
}
async setProviderType(type, rpcUrl = '', ticker = 'ETH', nickname = '') {
assert.notEqual(
assert.notStrictEqual(
type,
'rpc',
`NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`,
NETWORK_TYPE_RPC,
`NetworkController - cannot call "setProviderType" with type "${NETWORK_TYPE_RPC}". Use "setRpcTarget"`,
)
assert(
assert.ok(
INFURA_PROVIDER_TYPES.includes(type),
`NetworkController - Unknown rpc type "${type}"`,
`Unknown Infura provider type "${type}".`,
)
const { chainId } = NETWORK_TYPE_TO_ID_MAP[type]
this.setProviderConfig({ type, rpcUrl, chainId, ticker, nickname })
@ -209,7 +221,7 @@ export default class NetworkController extends EventEmitter {
getNetworkIdentifier() {
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 +240,7 @@ export default class NetworkController extends EventEmitter {
if (isInfura) {
this._configureInfuraProvider(type, this._infuraProjectId)
// url-based rpc endpoints
} else if (type === 'rpc') {
} else if (type === NETWORK_TYPE_RPC) {
this._configureStandardProvider(rpcUrl, chainId)
} else {
throw new Error(

@ -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]

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

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

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

@ -1,5 +1,5 @@
import { createAsyncMiddleware } from 'json-rpc-engine'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
/**
* Create middleware for handling certain methods and preprocessing permissions requests.

@ -1,13 +1,13 @@
import { strict as assert } from 'assert'
import { ObservableStore } from '@metamask/obs-store'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
import { normalize as normalizeAddress } from 'eth-sig-util'
import { isValidAddress } from 'ethereumjs-util'
import ethers from 'ethers'
import log from 'loglevel'
import { isPrefixedFormattedHexString } from '../lib/util'
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'
import { isPrefixedFormattedHexString } from '../../../shared/modules/utils'
export default class PreferencesController {
/**

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

@ -3,7 +3,7 @@ import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util'
import Transaction from 'ethereumjs-tx'
import EthQuery from 'ethjs-query'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
import abi from 'human-standard-token-abi'
import { ethers } from 'ethers'
import NonceTracker from 'nonce-tracker'

@ -1,5 +1,5 @@
import { isValidAddress } from 'ethereumjs-util'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
import { addHexPrefix } from '../../../lib/util'
import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'

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

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

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

@ -1,6 +1,9 @@
import extension from 'extensionizer'
import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'
import resolveEnsToIpfsContentId from './resolver'
const fetchWithTimeout = getFetchWithTimeout(30000)
const supportedTopLevelDomains = ['eth']
export default function setupEnsIpfsResolver({
@ -55,7 +58,9 @@ export default function setupEnsIpfsResolver({
)}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}`
try {
// 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) {
url = resolvedUrl
}

@ -1,9 +1,9 @@
import EventEmitter from 'events'
import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
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

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

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

@ -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.

@ -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

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

@ -1,13 +1,13 @@
import EventEmitter from 'events'
import assert from 'assert'
import { ObservableStore } from '@metamask/obs-store'
import { ethErrors } from 'eth-json-rpc-errors'
import { ethErrors } from 'eth-rpc-errors'
import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util'
import { isValidAddress } from 'ethereumjs-util'
import log from 'loglevel'
import jsonschema from 'jsonschema'
import { MESSAGE_TYPE } from '../../../shared/constants/app'
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

@ -14,7 +14,7 @@ import {
PLATFORM_CHROME,
PLATFORM_EDGE,
PLATFORM_BRAVE,
} from './enums'
} from '../../../shared/constants/app'
/**
* @see {@link getEnvironmentType}
@ -147,21 +147,6 @@ function checkForError() {
return new Error(lastError.message)
}
/**
* Checks whether the given value is a 0x-prefixed, non-zero, non-zero-padded,
* hexadecimal string.
*
* @param {any} value - The value to check.
* @returns {boolean} True if the value is a correctly formatted hex string,
* false otherwise.
*/
function isPrefixedFormattedHexString(value) {
if (typeof value !== 'string') {
return false
}
return /^0x[1-9a-f]+[0-9a-f]*$/iu.test(value)
}
/**
* Prefixes a hex string with '0x' or '-0x' and returns it. Idempotent.
*
@ -202,7 +187,6 @@ export {
hexToBn,
BnMultiplyByFraction,
checkForError,
isPrefixedFormattedHexString,
addHexPrefix,
bnToHex,
}

@ -2402,20 +2402,20 @@ export default class MetamaskController extends EventEmitter {
nickname,
rpcPrefs,
) {
await this.preferencesController.updateRpc({
this.networkController.setRpcTarget(
rpcUrl,
chainId,
ticker,
nickname,
rpcPrefs,
})
this.networkController.setRpcTarget(
)
await this.preferencesController.updateRpc({
rpcUrl,
chainId,
ticker,
nickname,
rpcPrefs,
)
})
return rpcUrl
}

@ -1,5 +1,5 @@
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

@ -1,7 +1,7 @@
import extension from 'extensionizer'
import { createExplorerLink as explorerLink } from '@metamask/etherscan-link'
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'
export default class ExtensionPlatform {

@ -12,12 +12,12 @@ import EthQuery from 'eth-query'
import StreamProvider from 'web3-stream-provider'
import log from 'loglevel'
import launchMetaMaskUi from '../../ui'
import ExtensionPlatform from './platforms/extension'
import { setupMultiplex } from './lib/stream-utils'
import {
ENVIRONMENT_TYPE_FULLSCREEN,
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'
start().catch(log.error)

@ -16,6 +16,6 @@ Passing messages from popup to background script
window.addEventListener('message', event => {
if (port && event.source === window && event.data) {
port.postMessage(event.data);
port.postMessage({ data: event.data });
}
});

@ -6,7 +6,7 @@ module.exports = function (api) {
'@babel/preset-env',
{
targets: {
browsers: ['chrome >= 63', 'firefox >= 56.2'],
browsers: ['chrome >= 63', 'firefox >= 68'],
},
},
],

@ -375,12 +375,10 @@ function createScriptTasks({ browserPlatforms, livereload }) {
METAMASK_DEBUG: opts.devMode,
METAMASK_ENVIRONMENT: environment,
METAMASK_VERSION: baseManifest.version,
METAMETRICS_PROJECT_ID: process.env.METAMETRICS_PROJECT_ID,
NODE_ENV: opts.devMode ? 'development' : 'production',
IN_TEST: opts.testing ? 'true' : false,
PUBNUB_SUB_KEY: process.env.PUBNUB_SUB_KEY || '',
PUBNUB_PUB_KEY: process.env.PUBNUB_PUB_KEY || '',
ETH_GAS_STATION_API_KEY: process.env.ETH_GAS_STATION_API_KEY || '',
CONF: opts.devMode ? conf : {},
SENTRY_DSN: process.env.SENTRY_DSN,
INFURA_PROJECT_ID: opts.testing

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

@ -86,7 +86,7 @@
"@metamask/logo": "^2.5.0",
"@metamask/obs-store": "^5.0.0",
"@popperjs/core": "^2.4.0",
"@reduxjs/toolkit": "^1.3.2",
"@reduxjs/toolkit": "^1.5.0",
"@sentry/browser": "^5.26.0",
"@sentry/integrations": "^5.26.0",
"@zxing/library": "^0.8.0",
@ -105,7 +105,6 @@
"end-of-stream": "^1.4.4",
"eth-block-tracker": "^4.4.2",
"eth-ens-namehash": "^2.0.8",
"eth-json-rpc-errors": "^2.0.2",
"eth-json-rpc-filters": "^4.2.1",
"eth-json-rpc-infura": "^5.1.0",
"eth-json-rpc-middleware": "^6.0.0",
@ -113,8 +112,9 @@
"eth-method-registry": "^2.0.0",
"eth-phishing-detect": "^1.1.14",
"eth-query": "^2.1.2",
"eth-rpc-errors": "^4.0.2",
"eth-sig-util": "^3.0.0",
"eth-trezor-keyring": "^0.4.0",
"eth-trezor-keyring": "^0.5.2",
"ethereum-ens-network-map": "^1.0.2",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-tx": "1.3.7",
@ -246,7 +246,7 @@
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.0.0",
"gulp-rtlcss": "^1.4.0",
"gulp-sass": "^4.0.0",
"gulp-sass": "^4.1.0",
"gulp-sourcemaps": "^2.6.0",
"gulp-stylelint": "^13.0.0",
"gulp-terser-js": "^5.2.2",
@ -259,7 +259,6 @@
"mocha": "^7.2.0",
"nock": "^9.0.14",
"node-fetch": "^2.6.1",
"node-sass": "^4.14.1",
"nyc": "^15.0.0",
"polyfill-crypto.getrandomvalues": "^1.0.0",
"prettier": "^2.1.1",
@ -275,7 +274,8 @@
"remote-redux-devtools": "^0.5.16",
"remotedev-server": "^0.3.1",
"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",
"serve-handler": "^6.1.2",
"ses": "0.11.0",

@ -6,19 +6,18 @@
* background - The background process that powers the extension
* @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'
const ENVIRONMENT_TYPE_NOTIFICATION = 'notification'
const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen'
const ENVIRONMENT_TYPE_BACKGROUND = 'background'
export const PLATFORM_BRAVE = 'Brave'
export const PLATFORM_CHROME = 'Chrome'
export const PLATFORM_EDGE = 'Edge'
export const PLATFORM_FIREFOX = 'Firefox'
export const PLATFORM_OPERA = 'Opera'
const PLATFORM_BRAVE = 'Brave'
const PLATFORM_CHROME = 'Chrome'
const PLATFORM_EDGE = 'Edge'
const PLATFORM_FIREFOX = 'Firefox'
const PLATFORM_OPERA = 'Opera'
const MESSAGE_TYPE = {
export const MESSAGE_TYPE = {
ETH_DECRYPT: 'eth_decrypt',
ETH_GET_ENCRYPTION_PUBLIC_KEY: 'eth_getEncryptionPublicKey',
ETH_SIGN: 'eth_sign',
@ -29,16 +28,3 @@ const MESSAGE_TYPE = {
WATCH_ASSET: 'wallet_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,
}

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

@ -3,6 +3,7 @@ export const RINKEBY = 'rinkeby'
export const KOVAN = 'kovan'
export const MAINNET = 'mainnet'
export const GOERLI = 'goerli'
export const NETWORK_TYPE_RPC = 'rpc'
export const MAINNET_NETWORK_ID = '1'
export const ROPSTEN_NETWORK_ID = '3'
@ -16,6 +17,12 @@ export const RINKEBY_CHAIN_ID = '0x4'
export const GOERLI_CHAIN_ID = '0x5'
export const KOVAN_CHAIN_ID = '0x2a'
/**
* The largest possible chain ID we can handle.
* Explanation: https://gist.github.com/rekmarks/a47bd5f2525936c4b8eee31a16345553
*/
export const MAX_SAFE_CHAIN_ID = 4503599627370476
export const ROPSTEN_DISPLAY_NAME = 'Ropsten'
export const RINKEBY_DISPLAY_NAME = 'Rinkeby'
export const KOVAN_DISPLAY_NAME = 'Kovan'

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

@ -1,3 +0,0 @@
### Shared Modules
This folder is reserved for modules that can be used globally within both the background and ui applications.

@ -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) {
const abortController = new window.AbortController()
const { signal } = abortController
@ -18,6 +24,6 @@ const fetchWithTimeout = ({ timeout = 120000 } = {}) => {
throw e
}
}
}
})
export default fetchWithTimeout
export default getFetchWithTimeout

@ -0,0 +1,30 @@
import { MAX_SAFE_CHAIN_ID } from '../constants/network'
/**
* Checks whether the given number primitive chain ID is safe.
* Because some cryptographic libraries we use expect the chain ID to be a
* number primitive, it must not exceed a certain size.
*
* @param {number} chainId - The chain ID to check for safety.
* @returns {boolean} Whether the given chain ID is safe.
*/
export function isSafeChainId(chainId) {
return (
Number.isSafeInteger(chainId) && chainId > 0 && chainId <= MAX_SAFE_CHAIN_ID
)
}
/**
* Checks whether the given value is a 0x-prefixed, non-zero, non-zero-padded,
* hexadecimal string.
*
* @param {any} value - The value to check.
* @returns {boolean} True if the value is a correctly formatted hex string,
* false otherwise.
*/
export function isPrefixedFormattedHexString(value) {
if (typeof value !== 'string') {
return false
}
return /^0x[1-9a-f]+[0-9a-f]*$/iu.test(value)
}

@ -2,6 +2,7 @@ import assert from 'assert'
import freeze from 'deep-freeze-strict'
import reducers from '../../../ui/app/ducks'
import * as actionConstants from '../../../ui/app/store/actionConstants'
import { NETWORK_TYPE_RPC } from '../../../shared/constants/network'
describe('config view actions', function () {
const initialState = {
@ -25,7 +26,7 @@ describe('config view actions', function () {
}
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')
})
})

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

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

@ -1,7 +1,7 @@
import { strict as assert } from 'assert'
import sinon from 'sinon'
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 {
METAMETRICS_ANONYMOUS_ID,

@ -1,12 +1,12 @@
import { ethErrors, ERROR_CODES } from 'eth-json-rpc-errors'
import { ethErrors, errorCodes } from 'eth-rpc-errors'
import deepFreeze from 'deep-freeze-strict'
import { ApprovalController } from '@metamask/controllers'
import _getRestrictedMethods from '../../../../../app/scripts/controllers/permissions/restrictedMethods'
import { CAVEAT_NAMES } from '../../../../../shared/constants/permissions'
import {
CAVEAT_NAMES,
CAVEAT_TYPES,
NOTIFICATION_NAMES,
} from '../../../../../app/scripts/controllers/permissions/enums'
@ -336,7 +336,7 @@ export const getters = deepFreeze({
return {
// name: 'EthereumRpcError',
message: `Failed to add 'eth_accounts' to '${origin}'.`,
code: ERROR_CODES.rpc.internal,
code: errorCodes.rpc.internal,
}
},
},

@ -8,7 +8,7 @@ import { ObservableStore } from '@metamask/obs-store'
import {
ROPSTEN_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 { createTestProviderTools } from '../../../stub/provider'
import SwapsController, {

@ -1,14 +1,16 @@
import assert from 'assert'
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 () {
nock('https://api.infura.io').get('/money').reply(200, '{"hodl": false}')
const fetch = fetchWithTimeout()
const response = await (await fetch('https://api.infura.io/money')).json()
const fetchWithTimeout = getFetchWithTimeout(30000)
const response = await (
await fetchWithTimeout('https://api.infura.io/money')
).json()
assert.deepEqual(response, {
hodl: false,
})
@ -20,12 +22,10 @@ describe('fetchWithTimeout', function () {
.delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}')
const fetch = fetchWithTimeout({
timeout: 123,
})
const fetchWithTimeout = getFetchWithTimeout(123)
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')
} catch (e) {
assert.ok(e)
@ -38,15 +38,20 @@ describe('fetchWithTimeout', function () {
.delay(2000)
.reply(200, '{"moon": "2012-12-21T11:11:11Z"}')
const fetch = fetchWithTimeout({
timeout: 123,
})
const fetchWithTimeout = getFetchWithTimeout(123)
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')
} catch (e) {
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')
})
})

@ -2,15 +2,15 @@ import { strict as assert } from 'assert'
import {
getEnvironmentType,
sufficientBalance,
isPrefixedFormattedHexString,
} from '../../../app/scripts/lib/util'
import { isPrefixedFormattedHexString } from '../../../shared/modules/utils'
import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_BACKGROUND,
} from '../../../app/scripts/lib/enums'
} from '../../../shared/constants/app'
describe('app utils', function () {
describe('getEnvironmentType', function () {

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

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

@ -4,7 +4,7 @@ import { debounce } from 'lodash'
import Fuse from 'fuse.js'
import InputAdornment from '@material-ui/core/InputAdornment'
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 Identicon from '../../ui/identicon'
import SiteIcon from '../../ui/site-icon'

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

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

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

@ -16,7 +16,7 @@ import {
import { useI18nContext } from '../../../hooks/useI18nContext'
import { useMetricEvent } from '../../../hooks/useMetricEvent'
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 }) {
const t = useI18nContext()

@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'
import SelectedAccount from '../selected-account'
import ConnectedStatusIndicator from '../connected-status-indicator'
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 { useI18nContext } from '../../../hooks/useI18nContext'
import { useMetricEvent } from '../../../hooks/useMetricEvent'

@ -6,7 +6,7 @@ import * as actions from '../../../store/actions'
import { resetCustomData as resetCustomGasData } from '../../../ducks/gas/gas.duck'
import isMobileView from '../../../../lib/is-mobile-view'
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
import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container'

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import log from 'loglevel'
import { BrowserQRCodeReader } from '@zxing/library'
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 WebcamUtils from '../../../../../lib/webcam-utils'
import PageContainerFooter from '../../../ui/page-container/page-container-footer/page-container-footer.component'

@ -1,21 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import {
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',
}
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
export default class NetworkDisplay extends Component {
static defaultProps = {
@ -23,9 +9,9 @@ export default class NetworkDisplay extends Component {
}
static propTypes = {
networkNickname: PropTypes.string.isRequired,
networkType: PropTypes.string.isRequired,
colored: PropTypes.bool,
network: PropTypes.string,
provider: PropTypes.object,
}
static contextTypes = {
@ -33,12 +19,11 @@ export default class NetworkDisplay extends Component {
}
renderNetworkIcon() {
const { network } = this.props
const networkClass = networkIdToTypeMap[network]
const { networkType } = this.props
return networkClass ? (
return networkType ? (
<div
className={`network-display__icon network-display__icon--${networkClass}`}
className={`network-display__icon network-display__icon--${networkType}`}
/>
) : (
<div
@ -52,24 +37,19 @@ export default class NetworkDisplay extends Component {
}
render() {
const {
colored,
network,
provider: { type, nickname },
} = this.props
const networkClass = networkIdToTypeMap[network]
const { colored, networkNickname, networkType } = this.props
return (
<div
className={classnames('network-display__container', {
'network-display__container--colored': colored,
[`network-display__container--${networkClass}`]:
colored && networkClass,
[`network-display__container--${networkType}`]:
colored && networkType,
})}
>
{networkClass ? (
{networkType ? (
<div
className={`network-display__icon network-display__icon--${networkClass}`}
className={`network-display__icon network-display__icon--${networkType}`}
/>
) : (
<div
@ -81,7 +61,9 @@ export default class NetworkDisplay extends Component {
/>
)}
<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>
)

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

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

@ -2,7 +2,7 @@ import { connect } from 'react-redux'
import { compose } from 'redux'
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 {
accountsWithSendEtherInfoSelector,

@ -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 }

@ -2,7 +2,7 @@ import { connect } from 'react-redux'
import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'
import { accountsWithSendEtherInfoSelector } from '../../../selectors'
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'
function mapStateToProps(state) {

@ -34,7 +34,7 @@ import {
setSwapsFromToken,
} from '../../../ducks/swaps/swaps'
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'
const EthOverview = ({ className }) => {

@ -27,7 +27,7 @@ import {
getCurrentKeyring,
getCurrentChainId,
} 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 SendIcon from '../../ui/icon/overview-send-icon.component'

@ -0,0 +1,55 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { omit } from 'lodash'
import Typography from '../typography'
import { COLORS } from '../../../helpers/constants/design-system'
export default function Chip({
className,
children,
borderColor = COLORS.UI1,
label,
labelProps = {},
leftIcon,
rightIcon,
onClick,
}) {
return (
<div
onClick={onClick}
className={classnames(className, 'chip', {
'chip--with-left-icon': Boolean(leftIcon),
'chip--with-right-icon': Boolean(rightIcon),
[`chip--${borderColor}`]: true,
})}
role="button"
tabIndex={0}
>
{leftIcon && <div className="chip__left-icon">{leftIcon}</div>}
{children ?? (
<Typography
className="chip__label"
variant="h6"
tag="span"
color="UI4"
{...labelProps}
>
{label}
</Typography>
)}
{rightIcon && <div className="chip__right-icon">{rightIcon}</div>}
</div>
)
}
Chip.propTypes = {
borderColor: PropTypes.oneOf(Object.values(COLORS)),
label: PropTypes.string,
children: PropTypes.node,
labelProps: PropTypes.shape(omit(Typography.propTypes, ['className'])),
leftIcon: PropTypes.node,
rightIcon: PropTypes.node,
className: PropTypes.string,
onClick: PropTypes.func,
}

@ -0,0 +1,48 @@
@use "design-system";
.chip {
$self: &;
border-radius: 100px;
border: 1px solid design-system.$ui-1;
padding: 8px 16px;
margin: 0 4px;
display: flex;
align-items: center;
width: max-content;
&__left-icon,
&__right-icon {
display: flex;
align-items: center;
}
@each $variant, $color in design-system.$color-map {
&--#{$variant} {
border-color: $color;
}
}
&--with-left-icon,
&--with-right-icon {
padding-top: 4px;
padding-bottom: 4px;
}
&--with-left-icon {
padding-left: 4px;
#{$self}__label {
margin-left: 8px;
}
}
&--with-right-icon {
padding-right: 4px;
#{$self}__label {
margin-right: 8px;
}
}
}

@ -0,0 +1,82 @@
/* eslint-disable react/prop-types */
import React from 'react'
import { select, text } from '@storybook/addon-knobs'
import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'
import ApproveIcon from '../icon/approve-icon.component'
import Identicon from '../identicon/identicon.component'
import Chip from '.'
export default {
title: 'Chip',
}
export const Plain = ({
leftIcon,
rightIcon,
label = 'Hello',
borderColor = COLORS.UI1,
fontColor = COLORS.BLACK,
}) => (
<Chip
leftIcon={leftIcon}
rightIcon={rightIcon}
label={text('label', label)}
labelProps={{
color: select('color', COLORS, fontColor),
variant: select('typography', TYPOGRAPHY, TYPOGRAPHY.H6),
}}
borderColor={select('borderColor', COLORS, borderColor)}
/>
)
export const WithLeftIcon = () => (
<Plain
label="Done!"
borderColor={COLORS.SUCCESS3}
fontColor={COLORS.SUCCESS3}
leftIcon={<ApproveIcon size={24} color="#4cd964" />}
/>
)
export const WithRightIcon = () => (
<Plain
label="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1"
borderColor={COLORS.UI4}
fontColor={COLORS.UI4}
rightIcon={
<Identicon
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1"
diameter={25}
/>
}
/>
)
export const WithBothIcons = () => (
<Plain
label="Account 1"
borderColor={COLORS.UI4}
fontColor={COLORS.UI4}
rightIcon={
<svg
width="10"
height="6"
viewBox="0 0 10 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9.45759 0.857142C9.45759 0.785714 9.42188 0.705357 9.3683 0.651785L8.92188 0.205357C8.8683 0.151785 8.78795 0.116071 8.71652 0.116071C8.64509 0.116071 8.56473 0.151785 8.51116 0.205357L5.00223 3.71429L1.4933 0.205357C1.43973 0.151785 1.35938 0.116071 1.28795 0.116071C1.20759 0.116071 1.13616 0.151785 1.08259 0.205357L0.636161 0.651785C0.582589 0.705357 0.546875 0.785714 0.546875 0.857142C0.546875 0.928571 0.582589 1.00893 0.636161 1.0625L4.79688 5.22321C4.85045 5.27679 4.9308 5.3125 5.00223 5.3125C5.07366 5.3125 5.15402 5.27679 5.20759 5.22321L9.3683 1.0625C9.42188 1.00893 9.45759 0.928571 9.45759 0.857142Z"
fill="#24292E"
/>
</svg>
}
leftIcon={
<Identicon
address="0x5CfE73b6021E818B776b421B1c4Db2474086a7e1"
diameter={25}
/>
}
/>
)

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

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

@ -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',
]),
}

@ -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;
}
}
}

@ -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>
)

@ -7,6 +7,7 @@
@import 'button/buttons';
@import 'card/index';
@import 'check-box/index';
@import 'chip/chip';
@import 'circle-icon/index';
@import 'currency-display/index';
@import 'currency-input/index';
@ -37,5 +38,6 @@
@import 'toggle-button/index';
@import 'token-balance/index';
@import 'tooltip/index';
@import 'typography/typography';
@import 'unit-input/index';
@import 'url-icon/index';

@ -74,3 +74,67 @@ $accent-pink: #ff45d8;
$neutral-white: #fff;
$neutral-black: $Black-100;
$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,
'transparent': transparent,
);

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

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

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

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

@ -329,8 +329,8 @@ export {
export const navigateBackToBuildQuote = (history) => {
return async (dispatch) => {
// TODO: Ensure any fetch in progress is cancelled
await dispatch(setBackgroundSwapRouteState(''))
dispatch(navigatedBackToBuildQuote())
history.push(BUILD_QUOTE_ROUTE)
}
}

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

@ -0,0 +1,42 @@
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: 'error-1',
ERROR2: 'error-2',
ERROR3: 'error-3',
ALERT1: 'alert-1',
ALERT2: 'alert-2',
ALERT3: 'alert-3',
MAINNET: 'mainnet',
ROPSTEN: 'ropsten',
KOVAN: 'kovan',
RINKEBY: 'rinkeby',
GOERLI: 'goerli',
TRANSPARENT: 'transparent',
}
export const TYPOGRAPHY = {
H1: 'h1',
H2: 'h2',
H3: 'h3',
H4: 'h4',
H5: 'h5',
H6: 'h6',
H7: 'h7',
H8: 'h8',
H9: 'h9',
Paragraph: 'paragraph',
}

@ -1,5 +1,5 @@
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 (
url,
@ -29,8 +29,8 @@ const fetchWithCache = async (
return cachedResponse
}
fetchOptions.headers.set('Content-Type', 'application/json')
const _fetch = timeout ? fetchWithTimeout({ timeout }) : window.fetch
const response = await _fetch(url, {
const fetchWithTimeout = getFetchWithTimeout(timeout)
const response = await fetchWithTimeout(url, {
referrerPolicy: 'no-referrer-when-downgrade',
body: null,
method: 'GET',

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

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

@ -4,7 +4,7 @@ import Button from '../../components/ui/button'
import Identicon from '../../components/ui/identicon'
import TokenBalance from '../../components/ui/token-balance'
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 {
static contextTypes = {

@ -9,7 +9,7 @@ import Identicon from '../../components/ui/identicon'
import Tooltip from '../../components/ui/tooltip'
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 { conversionUtil } from '../../helpers/utils/conversion-util'

@ -5,7 +5,7 @@ import AccountListItem from '../../components/app/account-list-item'
import Button from '../../components/ui/button'
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 { conversionUtil } from '../../helpers/utils/conversion-util'

@ -1,7 +1,7 @@
import ethUtil from 'ethereumjs-util'
import React, { Component } from 'react'
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 ConfirmPageContainer, {
ConfirmDetailRow,

@ -14,7 +14,7 @@ import {
DECRYPT_MESSAGE_REQUEST_PATH,
ENCRYPTION_PUBLIC_KEY_REQUEST_PATH,
} 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'
export default class ConfirmTransactionSwitch extends Component {

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

Loading…
Cancel
Save