mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add web3 usage metrics, prepare for web3 removal (#9144)
* add web3 usage metrics * move web3 metrics method to new middleware * rename some methods, files, and exports
This commit is contained in:
parent
d59fc79e0f
commit
e5cb63eea2
@ -7,7 +7,7 @@ import { CapabilitiesController as RpcCap } from 'rpc-cap'
|
||||
import { ethErrors } from 'eth-json-rpc-errors'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
import createMethodMiddleware from './methodMiddleware'
|
||||
import createPermissionsMethodMiddleware from './permissionsMethodMiddleware'
|
||||
import PermissionsLogController from './permissionsLog'
|
||||
|
||||
// Methods that do not require any permissions to use:
|
||||
@ -90,7 +90,7 @@ export class PermissionsController {
|
||||
|
||||
engine.push(this.permissionsLog.createMiddleware())
|
||||
|
||||
engine.push(createMethodMiddleware({
|
||||
engine.push(createPermissionsMethodMiddleware({
|
||||
addDomainMetadata: this.addDomainMetadata.bind(this),
|
||||
getAccounts: this.getAccounts.bind(this, origin),
|
||||
getUnlockPromise: () => this._getUnlockPromise(true),
|
||||
|
@ -4,7 +4,7 @@ import { ethErrors } from 'eth-json-rpc-errors'
|
||||
/**
|
||||
* Create middleware for handling certain methods and preprocessing permissions requests.
|
||||
*/
|
||||
export default function createMethodMiddleware ({
|
||||
export default function createPermissionsMethodMiddleware ({
|
||||
addDomainMetadata,
|
||||
getAccounts,
|
||||
getUnlockPromise,
|
@ -1,5 +1,3 @@
|
||||
/*global Web3*/
|
||||
|
||||
// need to make sure we aren't affected by overlapping namespaces
|
||||
// and that we dont affect the app with our namespace
|
||||
// mostly a fix for web3's BigNumber if AMD's "define" is defined...
|
||||
@ -37,9 +35,7 @@ import LocalMessageDuplexStream from 'post-message-stream'
|
||||
import { initProvider } from '@metamask/inpage-provider'
|
||||
|
||||
// TODO:deprecate:2020
|
||||
import 'web3/dist/web3.min.js'
|
||||
|
||||
import setupDappAutoReload from './lib/auto-reload.js'
|
||||
import setupWeb3 from './lib/setupWeb3.js'
|
||||
|
||||
restoreContextAfterImports()
|
||||
|
||||
@ -59,11 +55,9 @@ initProvider({
|
||||
connectionStream: metamaskStream,
|
||||
})
|
||||
|
||||
//
|
||||
// TODO:deprecate:2020
|
||||
//
|
||||
// Setup web3
|
||||
|
||||
// setup web3
|
||||
|
||||
if (typeof window.web3 !== 'undefined') {
|
||||
throw new Error(`MetaMask detected another web3.
|
||||
@ -73,18 +67,5 @@ if (typeof window.web3 !== 'undefined') {
|
||||
and try again.`)
|
||||
}
|
||||
|
||||
const web3 = new Web3(window.ethereum)
|
||||
web3.setProvider = function () {
|
||||
log.debug('MetaMask - overrode web3.setProvider')
|
||||
}
|
||||
log.debug('MetaMask - injected web3')
|
||||
|
||||
Object.defineProperty(window.ethereum, '_web3Ref', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
value: web3.eth,
|
||||
})
|
||||
|
||||
// setup dapp auto reload AND proxy web3
|
||||
setupDappAutoReload(web3, window.ethereum._publicConfigStore)
|
||||
// proxy web3, assign to window, and set up site auto reload
|
||||
setupWeb3(log)
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { getBackgroundMetaMetricState } from '../../../ui/app/selectors'
|
||||
import { sendMetaMetricsEvent } from '../../../ui/app/helpers/utils/metametrics.util'
|
||||
|
||||
export default function backEndMetaMetricsEvent (metaMaskState, eventData) {
|
||||
export default function backgroundMetaMetricsEvent (metaMaskState, eventData) {
|
||||
const stateEventData = getBackgroundMetaMetricState({ metamask: metaMaskState })
|
||||
|
||||
if (stateEventData.participateInMetaMetrics) {
|
||||
sendMetaMetricsEvent({
|
||||
...stateEventData,
|
||||
...eventData,
|
||||
category: 'Background',
|
||||
currentPath: '/background',
|
||||
})
|
||||
}
|
32
app/scripts/lib/createMethodMiddleware.js
Normal file
32
app/scripts/lib/createMethodMiddleware.js
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Returns a middleware that implements the following RPC methods:
|
||||
* - metamask_logInjectedWeb3Usage
|
||||
*
|
||||
* @param {Object} opts - The middleware options
|
||||
* @param {string} opts.origin - The origin for the middleware stack
|
||||
* @param {Function} opts.sendMetrics - A function for sending a metrics event
|
||||
* @returns {(req: any, res: any, next: Function, end: Function) => void}
|
||||
*/
|
||||
export default function createMethodMiddleware ({ origin, sendMetrics }) {
|
||||
return function methodMiddleware (req, res, next, end) {
|
||||
switch (req.method) {
|
||||
|
||||
case 'metamask_logInjectedWeb3Usage':
|
||||
|
||||
const { action, name } = req.params[0]
|
||||
|
||||
sendMetrics({
|
||||
action,
|
||||
name,
|
||||
customVariables: { origin },
|
||||
})
|
||||
|
||||
res.result = true
|
||||
break
|
||||
|
||||
default:
|
||||
return next()
|
||||
}
|
||||
return end()
|
||||
}
|
||||
}
|
@ -1,26 +1,67 @@
|
||||
/*global Web3*/
|
||||
|
||||
// TODO:deprecate:2020
|
||||
// Delete this file
|
||||
|
||||
export default function setupDappAutoReload (web3, observable) {
|
||||
import 'web3/dist/web3.min.js'
|
||||
|
||||
const shouldLogUsage = !([
|
||||
'docs.metamask.io',
|
||||
'metamask.github.io',
|
||||
'metamask.io',
|
||||
].includes(window.location.hostname))
|
||||
|
||||
export default function setupWeb3 (log) {
|
||||
// export web3 as a global, checking for usage
|
||||
let reloadInProgress = false
|
||||
let lastTimeUsed
|
||||
let lastSeenNetwork
|
||||
let hasBeenWarned = false
|
||||
|
||||
const web3 = new Web3(window.ethereum)
|
||||
web3.setProvider = function () {
|
||||
log.debug('MetaMask - overrode web3.setProvider')
|
||||
}
|
||||
log.debug('MetaMask - injected web3')
|
||||
|
||||
Object.defineProperty(window.ethereum, '_web3Ref', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
value: web3.eth,
|
||||
})
|
||||
|
||||
const web3Proxy = new Proxy(web3, {
|
||||
get: (_web3, key) => {
|
||||
|
||||
// get the time of use
|
||||
lastTimeUsed = Date.now()
|
||||
|
||||
// show warning once on web3 access
|
||||
if (!hasBeenWarned && key !== 'currentProvider') {
|
||||
if (!hasBeenWarned) {
|
||||
console.warn(`MetaMask: We will stop injecting web3 in Q4 2020.\nPlease see this article for more information: https://medium.com/metamask/no-longer-injecting-web3-js-4a899ad6e59e`)
|
||||
hasBeenWarned = true
|
||||
}
|
||||
|
||||
if (shouldLogUsage) {
|
||||
window.ethereum.request({
|
||||
method: 'metamask_logInjectedWeb3Usage',
|
||||
params: [{ action: 'window.web3 get', name: key }],
|
||||
})
|
||||
}
|
||||
|
||||
// return value normally
|
||||
return _web3[key]
|
||||
},
|
||||
set: (_web3, key, value) => {
|
||||
|
||||
if (shouldLogUsage) {
|
||||
window.ethereum.request({
|
||||
method: 'metamask_logInjectedWeb3Usage',
|
||||
params: [{ action: 'window.web3 set', name: key }],
|
||||
})
|
||||
}
|
||||
|
||||
// set value normally
|
||||
_web3[key] = value
|
||||
},
|
||||
@ -33,7 +74,7 @@ export default function setupDappAutoReload (web3, observable) {
|
||||
value: web3Proxy,
|
||||
})
|
||||
|
||||
observable.subscribe(function (state) {
|
||||
window.ethereum._publicConfigStore.subscribe((state) => {
|
||||
// if the auto refresh on network change is false do not
|
||||
// do anything
|
||||
if (!window.ethereum.autoRefreshOnNetworkChange) {
|
@ -19,6 +19,7 @@ import createEngineStream from 'json-rpc-middleware-stream/engineStream'
|
||||
import createFilterMiddleware from 'eth-json-rpc-filters'
|
||||
import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager'
|
||||
import createLoggerMiddleware from './lib/createLoggerMiddleware'
|
||||
import createMethodMiddleware from './lib/createMethodMiddleware'
|
||||
import createOriginMiddleware from './lib/createOriginMiddleware'
|
||||
import createTabIdMiddleware from './lib/createTabIdMiddleware'
|
||||
import createOnboardingMiddleware from './lib/createOnboardingMiddleware'
|
||||
@ -66,7 +67,7 @@ import {
|
||||
PhishingController,
|
||||
} from '@metamask/controllers'
|
||||
|
||||
import backEndMetaMetricsEvent from './lib/backend-metametrics'
|
||||
import backgroundMetaMetricsEvent from './lib/background-metametrics'
|
||||
|
||||
export default class MetamaskController extends EventEmitter {
|
||||
|
||||
@ -249,18 +250,11 @@ export default class MetamaskController extends EventEmitter {
|
||||
this.platform.showTransactionNotification(txMeta)
|
||||
|
||||
const { txReceipt } = txMeta
|
||||
const participateInMetaMetrics = this.preferencesController.getParticipateInMetaMetrics()
|
||||
if (txReceipt && txReceipt.status === '0x0' && participateInMetaMetrics) {
|
||||
const metamaskState = await this.getState()
|
||||
backEndMetaMetricsEvent(metamaskState, {
|
||||
customVariables: {
|
||||
errorMessage: txMeta.simulationFails?.reason,
|
||||
},
|
||||
eventOpts: {
|
||||
category: 'Background',
|
||||
if (txReceipt && txReceipt.status === '0x0') {
|
||||
this.sendBackgroundMetaMetrics({
|
||||
action: 'Transactions',
|
||||
name: 'On Chain Failure',
|
||||
},
|
||||
customVariables: { errorMessage: txMeta.simulationFails?.reason },
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1637,6 +1631,10 @@ export default class MetamaskController extends EventEmitter {
|
||||
location,
|
||||
registerOnboarding: this.onboardingController.registerOnboarding,
|
||||
}))
|
||||
engine.push(createMethodMiddleware({
|
||||
origin,
|
||||
sendMetrics: this.sendBackgroundMetaMetrics.bind(this),
|
||||
}))
|
||||
// filter and subscription polyfills
|
||||
engine.push(filterMiddleware)
|
||||
engine.push(subscriptionManager.middleware)
|
||||
@ -1837,6 +1835,22 @@ export default class MetamaskController extends EventEmitter {
|
||||
return nonceLock.nextNonce
|
||||
}
|
||||
|
||||
async sendBackgroundMetaMetrics ({ action, name, customVariables } = {}) {
|
||||
|
||||
if (!action || !name) {
|
||||
throw new Error('Must provide action and name.')
|
||||
}
|
||||
|
||||
const metamaskState = await this.getState()
|
||||
backgroundMetaMetricsEvent(metamaskState, {
|
||||
customVariables,
|
||||
eventOpts: {
|
||||
action,
|
||||
name,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CONFIG
|
||||
//=============================================================================
|
||||
|
@ -23,7 +23,7 @@ const METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE = 'gasLimitChange'
|
||||
const METAMETRICS_CUSTOM_GAS_PRICE_CHANGE = 'gasPriceChange'
|
||||
const METAMETRICS_CUSTOM_FUNCTION_TYPE = 'functionType'
|
||||
const METAMETRICS_CUSTOM_RECIPIENT_KNOWN = 'recipientKnown'
|
||||
const METAMETRICS_CUSTOM_CONFIRM_SCREEN_ORIGIN = 'origin'
|
||||
const METAMETRICS_REQUEST_ORIGIN = 'origin'
|
||||
const METAMETRICS_CUSTOM_FROM_NETWORK = 'fromNetwork'
|
||||
const METAMETRICS_CUSTOM_TO_NETWORK = 'toNetwork'
|
||||
const METAMETRICS_CUSTOM_ERROR_FIELD = 'errorField'
|
||||
@ -36,7 +36,7 @@ const METAMETRICS_CUSTOM_ASSET_SELECTED = 'assetSelected'
|
||||
const customVariableNameIdMap = {
|
||||
[METAMETRICS_CUSTOM_FUNCTION_TYPE]: 1,
|
||||
[METAMETRICS_CUSTOM_RECIPIENT_KNOWN]: 2,
|
||||
[METAMETRICS_CUSTOM_CONFIRM_SCREEN_ORIGIN]: 3,
|
||||
[METAMETRICS_REQUEST_ORIGIN]: 3,
|
||||
[METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE]: 4,
|
||||
[METAMETRICS_CUSTOM_GAS_PRICE_CHANGE]: 5,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user