@ -24,45 +24,19 @@ const Sqrl = require('squirrelly');
const lavapack = require ( '@lavamoat/lavapack' ) ;
const lavapack = require ( '@lavamoat/lavapack' ) ;
const lavamoatBrowserify = require ( 'lavamoat-browserify' ) ;
const lavamoatBrowserify = require ( 'lavamoat-browserify' ) ;
const terser = require ( 'terser' ) ;
const terser = require ( 'terser' ) ;
const ini = require ( 'ini' ) ;
const bifyModuleGroups = require ( 'bify-module-groups' ) ;
const bifyModuleGroups = require ( 'bify-module-groups' ) ;
const configPath = path . resolve ( _ _dirname , '..' , '..' , '.metamaskrc' ) ;
let configContents = '' ;
try {
configContents = readFileSync ( configPath , {
encoding : 'utf8' ,
} ) ;
} catch ( error ) {
if ( error . code !== 'ENOENT' ) {
throw error ;
}
}
const metamaskrc = {
INFURA _PROJECT _ID : process . env . INFURA _PROJECT _ID ,
INFURA _BETA _PROJECT _ID : process . env . INFURA _BETA _PROJECT _ID ,
INFURA _FLASK _PROJECT _ID : process . env . INFURA _FLASK _PROJECT _ID ,
INFURA _PROD _PROJECT _ID : process . env . INFURA _PROD _PROJECT _ID ,
ONBOARDING _V2 : process . env . ONBOARDING _V2 ,
COLLECTIBLES _V1 : process . env . COLLECTIBLES _V1 ,
PHISHING _WARNING _PAGE _URL : process . env . PHISHING _WARNING _PAGE _URL ,
SEGMENT _HOST : process . env . SEGMENT _HOST ,
SEGMENT _WRITE _KEY : process . env . SEGMENT _WRITE _KEY ,
SEGMENT _BETA _WRITE _KEY : process . env . SEGMENT _BETA _WRITE _KEY ,
SEGMENT _FLASK _WRITE _KEY : process . env . SEGMENT _FLASK _WRITE _KEY ,
SEGMENT _PROD _WRITE _KEY : process . env . SEGMENT _PROD _WRITE _KEY ,
SENTRY _DSN _DEV :
process . env . SENTRY _DSN _DEV ||
'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' ,
SIWE _V1 : process . env . SIWE _V1 ,
... ini . parse ( configContents ) ,
} ;
const { streamFlatMap } = require ( '../stream-flat-map' ) ;
const { streamFlatMap } = require ( '../stream-flat-map' ) ;
const { BuildType } = require ( '../lib/build-type' ) ;
const { BuildType } = require ( '../lib/build-type' ) ;
const { BUILD _TARGETS } = require ( './constants' ) ;
const { BUILD _TARGETS , ENVIRONMENT } = require ( './constants' ) ;
const { logError } = require ( './utils' ) ;
const { getConfig , getProductionConfig } = require ( './config' ) ;
const {
isDevBuild ,
isTestBuild ,
getEnvironment ,
logError ,
} = require ( './utils' ) ;
const {
const {
createTask ,
createTask ,
@ -74,81 +48,28 @@ const {
createRemoveFencedCodeTransform ,
createRemoveFencedCodeTransform ,
} = require ( './transforms/remove-fenced-code' ) ;
} = require ( './transforms/remove-fenced-code' ) ;
/ * *
* The build environment . This describes the environment this build was produced in .
* /
const ENVIRONMENT = {
DEVELOPMENT : 'development' ,
PRODUCTION : 'production' ,
OTHER : 'other' ,
PULL _REQUEST : 'pull-request' ,
RELEASE _CANDIDATE : 'release-candidate' ,
STAGING : 'staging' ,
TESTING : 'testing' ,
} ;
/ * *
* Returns whether the current build is a development build or not .
*
* @ param { BUILD _TARGETS } buildTarget - The current build target .
* @ returns Whether the current build is a development build .
* /
function isDevBuild ( buildTarget ) {
return (
buildTarget === BUILD _TARGETS . DEVELOPMENT ||
buildTarget === BUILD _TARGETS . E2E _TEST _DEV
) ;
}
/ * *
* Returns whether the current build is an e2e test build or not .
*
* @ param { BUILD _TARGETS } buildTarget - The current build target .
* @ returns Whether the current build is an e2e test build .
* /
function isTestBuild ( buildTarget ) {
return (
buildTarget === BUILD _TARGETS . E2E _TEST ||
buildTarget === BUILD _TARGETS . E2E _TEST _DEV
) ;
}
/ * *
* Get a value from the configuration , and confirm that it is set .
*
* @ param { string } key - The configuration key to retrieve .
* @ returns { string } The config entry requested .
* @ throws { Error } Throws if the requested key is missing .
* /
function getConfigValue ( key ) {
const value = metamaskrc [ key ] ;
if ( ! value ) {
throw new Error ( ` Missing config entry for ' ${ key } ' ` ) ;
}
return value ;
}
/ * *
/ * *
* Get the appropriate Infura project ID .
* Get the appropriate Infura project ID .
*
*
* @ param { object } options - The Infura project ID options .
* @ param { object } options - The Infura project ID options .
* @ param { BuildType } options . buildType - The current build type .
* @ param { BuildType } options . buildType - The current build type .
* @ param { object } options . config - The environment variable configuration .
* @ param { ENVIRONMENT [ keyof ENVIRONMENT ] } options . environment - The build environment .
* @ param { ENVIRONMENT [ keyof ENVIRONMENT ] } options . environment - The build environment .
* @ param { boolean } options . testing - Whether this is a test build or not .
* @ param { boolean } options . testing - Whether this is a test build or not .
* @ returns { string } The Infura project ID .
* @ returns { string } The Infura project ID .
* /
* /
function getInfuraProjectId ( { buildType , environment , testing } ) {
function getInfuraProjectId ( { buildType , config , environment , testing } ) {
if ( testing ) {
if ( testing ) {
return '00000000000000000000000000000000' ;
return '00000000000000000000000000000000' ;
} else if ( environment !== ENVIRONMENT . PRODUCTION ) {
} else if ( environment !== ENVIRONMENT . PRODUCTION ) {
// Skip validation because this is unset on PRs from forks.
// Skip validation because this is unset on PRs from forks.
return metamaskr c. INFURA _PROJECT _ID ;
return config . INFURA _PROJECT _ID ;
} else if ( buildType === BuildType . main ) {
} else if ( buildType === BuildType . main ) {
return getConfigValue ( 'INFURA_PROD_PROJECT_ID' ) ;
return config . INFURA _PROD _PROJECT _ID ;
} else if ( buildType === BuildType . beta ) {
} else if ( buildType === BuildType . beta ) {
return getConfigValue ( 'INFURA_BETA_PROJECT_ID' ) ;
return config . INFURA _BETA _PROJECT _ID ;
} else if ( buildType === BuildType . flask ) {
} else if ( buildType === BuildType . flask ) {
return getConfigValue ( 'INFURA_FLASK_PROJECT_ID' ) ;
return config . INFURA _FLASK _PROJECT _ID ;
}
}
throw new Error ( ` Invalid build type: ' ${ buildType } ' ` ) ;
throw new Error ( ` Invalid build type: ' ${ buildType } ' ` ) ;
}
}
@ -158,19 +79,20 @@ function getInfuraProjectId({ buildType, environment, testing }) {
*
*
* @ param { object } options - The Segment write key options .
* @ param { object } options - The Segment write key options .
* @ param { BuildType } options . buildType - The current build type .
* @ param { BuildType } options . buildType - The current build type .
* @ param { object } options . config - The environment variable configuration .
* @ param { keyof ENVIRONMENT } options . environment - The current build environment .
* @ param { keyof ENVIRONMENT } options . environment - The current build environment .
* @ returns { string } The Segment write key .
* @ returns { string } The Segment write key .
* /
* /
function getSegmentWriteKey ( { buildType , environment } ) {
function getSegmentWriteKey ( { buildType , config , environment } ) {
if ( environment !== ENVIRONMENT . PRODUCTION ) {
if ( environment !== ENVIRONMENT . PRODUCTION ) {
// Skip validation because this is unset on PRs from forks, and isn't necessary for development builds.
// Skip validation because this is unset on PRs from forks, and isn't necessary for development builds.
return metamaskr c. SEGMENT _WRITE _KEY ;
return config . SEGMENT _WRITE _KEY ;
} else if ( buildType === BuildType . main ) {
} else if ( buildType === BuildType . main ) {
return getConfigValue ( 'SEGMENT_PROD_WRITE_KEY' ) ;
return config . SEGMENT _PROD _WRITE _KEY ;
} else if ( buildType === BuildType . beta ) {
} else if ( buildType === BuildType . beta ) {
return getConfigValue ( 'SEGMENT_BETA_WRITE_KEY' ) ;
return config . SEGMENT _BETA _WRITE _KEY ;
} else if ( buildType === BuildType . flask ) {
} else if ( buildType === BuildType . flask ) {
return getConfigValue ( 'SEGMENT_FLASK_WRITE_KEY' ) ;
return config . SEGMENT _FLASK _WRITE _KEY ;
}
}
throw new Error ( ` Invalid build type: ' ${ buildType } ' ` ) ;
throw new Error ( ` Invalid build type: ' ${ buildType } ' ` ) ;
}
}
@ -179,11 +101,12 @@ function getSegmentWriteKey({ buildType, environment }) {
* Get the URL for the phishing warning page , if it has been set .
* Get the URL for the phishing warning page , if it has been set .
*
*
* @ param { object } options - The phishing warning page options .
* @ param { object } options - The phishing warning page options .
* @ param { object } options . config - The environment variable configuration .
* @ param { boolean } options . testing - Whether this is a test build or not .
* @ param { boolean } options . testing - Whether this is a test build or not .
* @ returns { string } The URL for the phishing warning page , or ` undefined ` if no URL is set .
* @ returns { string } The URL for the phishing warning page , or ` undefined ` if no URL is set .
* /
* /
function getPhishingWarningPageUrl ( { testing } ) {
function getPhishingWarningPageUrl ( { config , testing } ) {
let phishingWarningPageUrl = metamaskr c. PHISHING _WARNING _PAGE _URL ;
let phishingWarningPageUrl = config . PHISHING _WARNING _PAGE _URL ;
if ( ! phishingWarningPageUrl ) {
if ( ! phishingWarningPageUrl ) {
phishingWarningPageUrl = testing
phishingWarningPageUrl = testing
@ -259,35 +182,35 @@ function createScriptTasks({
shouldLintFenceFiles ,
shouldLintFenceFiles ,
version ,
version ,
} ) {
} ) {
// interna l tasks
// high leve l tasks
const core = {
return {
// dev tasks (live reload)
// dev tasks (live reload)
dev : createTasksForScriptBundles ( {
dev : createTasksForScriptBundles ( {
buildTarget : BUILD _TARGETS . DEVELOPMENT ,
buildTarget : BUILD _TARGETS . DEV ,
taskPrefix : 'scripts:core:dev' ,
taskPrefix : 'scripts:core:dev' ,
} ) ,
} ) ,
// production-like distributable build
dist : createTasksForScriptBundles ( {
buildTarget : BUILD _TARGETS . DIST ,
taskPrefix : 'scripts:core:dist' ,
} ) ,
// production
// production
prod : createTasksForScriptBundles ( {
prod : createTasksForScriptBundles ( {
buildTarget : BUILD _TARGETS . PRODUCTION ,
buildTarget : BUILD _TARGETS . PROD ,
taskPrefix : 'scripts:core:prod' ,
taskPrefix : 'scripts:core:prod' ,
} ) ,
} ) ,
// built for CI tests
// built for CI tests
test : createTasksForScriptBundles ( {
test : createTasksForScriptBundles ( {
buildTarget : BUILD _TARGETS . E2E _ TEST,
buildTarget : BUILD _TARGETS . TEST ,
taskPrefix : 'scripts:core:test' ,
taskPrefix : 'scripts:core:test' ,
} ) ,
} ) ,
// built for CI test debugging
// built for CI test debugging
testDev : createTasksForScriptBundles ( {
testDev : createTasksForScriptBundles ( {
buildTarget : BUILD _TARGETS . E2E _ TEST_DEV ,
buildTarget : BUILD _TARGETS . TEST _DEV ,
taskPrefix : 'scripts:core:test-live' ,
taskPrefix : 'scripts:core:test-live' ,
} ) ,
} ) ,
} ;
} ;
// high level tasks
const { dev , test , testDev , prod } = core ;
return { dev , test , testDev , prod } ;
/ * *
/ * *
* Define tasks for building the JavaScript modules used by the extension .
* Define tasks for building the JavaScript modules used by the extension .
* This function returns a single task that builds JavaScript modules in
* This function returns a single task that builds JavaScript modules in
@ -595,7 +518,7 @@ function createFactoredBuild({
const reloadOnChange = isDevBuild ( buildTarget ) ;
const reloadOnChange = isDevBuild ( buildTarget ) ;
const minify = ! isDevBuild ( buildTarget ) ;
const minify = ! isDevBuild ( buildTarget ) ;
const envVars = getEnvironmentVariables ( {
const envVars = await getEnvironmentVariables ( {
buildTarget ,
buildTarget ,
buildType ,
buildType ,
version ,
version ,
@ -823,11 +746,11 @@ function createNormalBundle({
const minify = Boolean ( devMode ) === false ;
const minify = Boolean ( devMode ) === false ;
const envVars = {
const envVars = {
... getEnvironmentVariables ( {
... ( await getEnvironmentVariables ( {
buildTarget ,
buildTarget ,
buildType ,
buildType ,
version ,
version ,
} ) ,
} ) ) ,
... extraEnvironmentVariables ,
... extraEnvironmentVariables ,
} ;
} ;
setupBundlerDefaults ( buildConfiguration , {
setupBundlerDefaults ( buildConfiguration , {
@ -915,7 +838,7 @@ function setupBundlerDefaults(
} ) ;
} ) ;
// Ensure react-devtools is only included in dev builds
// Ensure react-devtools is only included in dev builds
if ( buildTarget !== BUILD _TARGETS . DEVELOPMENT ) {
if ( buildTarget !== BUILD _TARGETS . DEV ) {
bundlerOpts . manualIgnore . push ( 'react-devtools' ) ;
bundlerOpts . manualIgnore . push ( 'react-devtools' ) ;
bundlerOpts . manualIgnore . push ( 'remote-redux-devtools' ) ;
bundlerOpts . manualIgnore . push ( 'remote-redux-devtools' ) ;
}
}
@ -1081,20 +1004,22 @@ async function createBundle(buildConfiguration, { reloadOnChange }) {
* @ param { string } options . version - The current version of the extension .
* @ param { string } options . version - The current version of the extension .
* @ returns { object } A map of environment variables to inject .
* @ returns { object } A map of environment variables to inject .
* /
* /
function getEnvironmentVariables ( { buildTarget , buildType , version } ) {
async function getEnvironmentVariables ( { buildTarget , buildType , version } ) {
const environment = getEnvironment ( { buildTarget } ) ;
const environment = getEnvironment ( { buildTarget } ) ;
if ( environment === ENVIRONMENT . PRODUCTION && ! process . env . SENTRY _DSN ) {
const config =
throw new Error ( 'Missing SENTRY_DSN environment variable' ) ;
environment === ENVIRONMENT . PRODUCTION
}
? await getProductionConfig ( buildType )
: await getConfig ( ) ;
const devMode = isDevBuild ( buildTarget ) ;
const devMode = isDevBuild ( buildTarget ) ;
const testing = isTestBuild ( buildTarget ) ;
const testing = isTestBuild ( buildTarget ) ;
return {
return {
COLLECTIBLES _V1 : metamaskr c. COLLECTIBLES _V1 === '1' ,
COLLECTIBLES _V1 : config . COLLECTIBLES _V1 === '1' ,
CONF : devMode ? metamaskr c : { } ,
CONF : devMode ? config : { } ,
IN _TEST : testing ,
IN _TEST : testing ,
INFURA _PROJECT _ID : getInfuraProjectId ( {
INFURA _PROJECT _ID : getInfuraProjectId ( {
buildType ,
buildType ,
config ,
environment ,
environment ,
testing ,
testing ,
} ) ,
} ) ,
@ -1103,39 +1028,19 @@ function getEnvironmentVariables({ buildTarget, buildType, version }) {
METAMASK _VERSION : version ,
METAMASK _VERSION : version ,
METAMASK _BUILD _TYPE : buildType ,
METAMASK _BUILD _TYPE : buildType ,
NODE _ENV : devMode ? ENVIRONMENT . DEVELOPMENT : ENVIRONMENT . PRODUCTION ,
NODE _ENV : devMode ? ENVIRONMENT . DEVELOPMENT : ENVIRONMENT . PRODUCTION ,
ONBOARDING _V2 : metamaskr c. ONBOARDING _V2 === '1' ,
ONBOARDING _V2 : config . ONBOARDING _V2 === '1' ,
PHISHING _WARNING _PAGE _URL : getPhishingWarningPageUrl ( { testing } ) ,
PHISHING _WARNING _PAGE _URL : getPhishingWarningPageUrl ( { config , testing } ) ,
PUBNUB _PUB _KEY : process . env . PUBNUB _PUB _KEY || '' ,
PUBNUB _PUB _KEY : config . PUBNUB _PUB _KEY || '' ,
PUBNUB _SUB _KEY : process . env . PUBNUB _SUB _KEY || '' ,
PUBNUB _SUB _KEY : config . PUBNUB _SUB _KEY || '' ,
SEGMENT _HOST : metamaskr c. SEGMENT _HOST ,
SEGMENT _HOST : config . SEGMENT _HOST ,
SEGMENT _WRITE _KEY : getSegmentWriteKey ( { buildType , environment } ) ,
SEGMENT _WRITE _KEY : getSegmentWriteKey ( { buildType , config , environment } ) ,
SENTRY _DSN : process . env . SENTRY _DSN ,
SENTRY _DSN : config . SENTRY _DSN ,
SENTRY _DSN _DEV : metamaskr c. SENTRY _DSN _DEV ,
SENTRY _DSN _DEV : config . SENTRY _DSN _DEV ,
SIWE _V1 : metamaskr c. SIWE _V1 === '1' ,
SIWE _V1 : config . SIWE _V1 === '1' ,
SWAPS _USE _DEV _APIS : process . env . SWAPS _USE _DEV _APIS === '1' ,
SWAPS _USE _DEV _APIS : config . SWAPS _USE _DEV _APIS === '1' ,
} ;
} ;
}
}
function getEnvironment ( { buildTarget } ) {
// get environment slug
if ( isDevBuild ( buildTarget ) ) {
return ENVIRONMENT . DEVELOPMENT ;
} else if ( isTestBuild ( buildTarget ) ) {
return ENVIRONMENT . TESTING ;
} else if ( process . env . CIRCLE _BRANCH === 'master' ) {
return ENVIRONMENT . PRODUCTION ;
} else if (
/^Version-v(\d+)[.](\d+)[.](\d+)/u . test ( process . env . CIRCLE _BRANCH )
) {
return ENVIRONMENT . RELEASE _CANDIDATE ;
} else if ( process . env . CIRCLE _BRANCH === 'develop' ) {
return ENVIRONMENT . STAGING ;
} else if ( process . env . CIRCLE _PULL _REQUEST ) {
return ENVIRONMENT . PULL _REQUEST ;
}
return ENVIRONMENT . OTHER ;
}
function renderHtmlFile ( {
function renderHtmlFile ( {
htmlName ,
htmlName ,
groupSet ,
groupSet ,