1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +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/**
.vscode/**
test/e2e/send-eth-with-private-key-test/**
*.scss

View File

@ -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({
patterns: [
{
from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('fonts', 'fontawesome'),
},
],
}))
config.plugins.push(
new CopyWebpackPlugin({
patterns: [
{
from: path.join(
'node_modules',
'@fortawesome',
'fontawesome-free',
'webfonts',
),
to: path.join('fonts', 'fontawesome'),
},
],
}),
)
return config
},
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,25 +9,25 @@ 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 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',
@ -161,7 +161,7 @@ export default class NetworkController extends EventEmitter {
setRpcTarget(rpcUrl, chainId, ticker = 'ETH', nickname = '', rpcPrefs) {
this.setProviderConfig({
type: 'rpc',
type: NETWORK_TYPE_RPC,
rpcUrl,
chainId,
ticker,
@ -173,8 +173,8 @@ export default class NetworkController extends EventEmitter {
async setProviderType(type, rpcUrl = '', ticker = 'ETH', nickname = '') {
assert.notEqual(
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(
INFURA_PROVIDER_TYPES.includes(type),
@ -209,7 +209,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 +228,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(

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]

View File

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

View File

@ -6,10 +6,7 @@ import { CapabilitiesController as RpcCap } from 'rpc-cap'
import { ethErrors } from 'eth-json-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

View File

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

View File

@ -7,7 +7,7 @@ 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'
export default class PreferencesController {
/**

View File

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

View File

@ -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'
/**

View File

@ -3,9 +3,9 @@ import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-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

View File

@ -2,8 +2,8 @@ import EventEmitter from 'events'
import { ObservableStore } from '@metamask/obs-store'
import { ethErrors } from 'eth-json-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

View File

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

View File

@ -2,8 +2,8 @@ import EventEmitter from 'events'
import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-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

View File

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

View File

@ -3,9 +3,9 @@ import { ObservableStore } from '@metamask/obs-store'
import ethUtil from 'ethereumjs-util'
import { ethErrors } from 'eth-json-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

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.

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

View File

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

View File

@ -6,8 +6,8 @@ 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ import {
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 () {

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,8 @@ import {
NETWORKS_ROUTE,
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,
isPrefixedFormattedHexString,
@ -117,7 +118,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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 }

View File

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

View File

@ -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 }) => {

View File

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

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 'token-balance/index';
@import 'tooltip/index';
@import 'typography/typography';
@import 'unit-input/index';
@import 'url-icon/index';

View File

@ -74,3 +74,66 @@ $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,
);

View File

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

View File

@ -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-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 {
font-style: normal;
font-weight: normal;
font-size: $font-size-h1;
font-family: $font-family;
line-height: 140%;
@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');
}

View File

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

View File

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

View File

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

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 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',

View File

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

View File

@ -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,19 +481,17 @@ export async function jsonRpcRequest(rpcUrl, rpcMethod, rpcParams = []) {
headers.Authorization = `Basic ${encodedAuth}`
fetchUrl = `${origin}${pathname}${search}`
}
const jsonRpcResponse = await window
.fetch(fetchUrl, {
method: 'POST',
body: JSON.stringify({
id: Date.now().toString(),
jsonrpc: '2.0',
method: rpcMethod,
params: rpcParams,
}),
headers,
cache: 'default',
})
.then((httpResponse) => httpResponse.json())
const jsonRpcResponse = await fetchWithTimeout(fetchUrl, {
method: 'POST',
body: JSON.stringify({
id: Date.now().toString(),
jsonrpc: '2.0',
method: rpcMethod,
params: rpcParams,
}),
headers,
cache: 'default',
}).then((httpResponse) => httpResponse.json())
if (
!jsonRpcResponse ||

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ import SignatureRequest from '../../components/app/signature-request'
import SignatureRequestOriginal from '../../components/app/signature-request-original'
import Loading from '../../components/ui/loading-screen'
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'
function mapStateToProps(state) {

View File

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

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
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 {
static contextTypes = {

View File

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

View File

@ -2,7 +2,7 @@ import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
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 PermissionPageContainer from '../../components/app/permission-page-container'
import ChooseAccount from './choose-account'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,8 @@ import {
showModal,
} from '../../../store/actions'
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 NetworksTab from './networks-tab.component'
import { defaultNetworksData } from './networks-tab.constants'
@ -37,7 +38,7 @@ const mapStateToProps = (state, ownProps) => {
return {
label: rpc.nickname,
iconColor: '#6A737D',
providerType: 'rpc',
providerType: NETWORK_TYPE_RPC,
rpcUrl: rpc.rpcUrl,
chainId: rpc.chainId,
ticker: rpc.ticker,
@ -61,7 +62,7 @@ const mapStateToProps = (state, ownProps) => {
networksToRender.find((network) => {
return (
network.rpcUrl === provider.rpcUrl ||
(network.providerType !== 'rpc' &&
(network.providerType !== NETWORK_TYPE_RPC &&
network.providerType === provider.type)
)
}) || {}

View File

@ -3,7 +3,7 @@ import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { getAddressBookEntryName } from '../../selectors'
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 { getMostRecentOverviewPage } from '../../ducks/history/history'

View File

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

View File

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

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