mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
@metamask/inpage-provider@^8.0.0 (#8640)
* @metamask/inpage-provider@^8.0.0 * Replace public config store with JSON-RPC notifications * Encapsulate notification permissioning in permissions controller * Update prefix of certain internal RPC methods and notifications * Add accounts to getProviderState * Send accounts with isUnlocked notification (#10007) * Rename provider streams, notify provider of stream failures (#10006)
This commit is contained in:
parent
55e5f5513c
commit
3bf94164ac
@ -16,16 +16,13 @@ const inpageContent = fs.readFileSync(
|
|||||||
const inpageSuffix = `//# sourceURL=${extension.runtime.getURL('inpage.js')}\n`
|
const inpageSuffix = `//# sourceURL=${extension.runtime.getURL('inpage.js')}\n`
|
||||||
const inpageBundle = inpageContent + inpageSuffix
|
const inpageBundle = inpageContent + inpageSuffix
|
||||||
|
|
||||||
// Eventually this streaming injection could be replaced with:
|
const CONTENT_SCRIPT = 'metamask-contentscript'
|
||||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction
|
const INPAGE = 'metamask-inpage'
|
||||||
//
|
const PROVIDER = 'metamask-provider'
|
||||||
// But for now that is only Firefox
|
|
||||||
// If we create a FireFox-only code path using that API,
|
|
||||||
// MetaMask will be much faster loading and performant on Firefox.
|
|
||||||
|
|
||||||
if (shouldInjectProvider()) {
|
if (shouldInjectProvider()) {
|
||||||
injectScript(inpageBundle)
|
injectScript(inpageBundle)
|
||||||
start()
|
setupStreams()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,15 +43,6 @@ function injectScript(content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the stream communication and submits site metadata
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
async function start() {
|
|
||||||
await setupStreams()
|
|
||||||
await domIsReady()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up two-way communication streams between the
|
* Sets up two-way communication streams between the
|
||||||
* browser extension and local per-page browser context.
|
* browser extension and local per-page browser context.
|
||||||
@ -63,10 +51,10 @@ async function start() {
|
|||||||
async function setupStreams() {
|
async function setupStreams() {
|
||||||
// the transport-specific streams for communication between inpage and background
|
// the transport-specific streams for communication between inpage and background
|
||||||
const pageStream = new LocalMessageDuplexStream({
|
const pageStream = new LocalMessageDuplexStream({
|
||||||
name: 'contentscript',
|
name: CONTENT_SCRIPT,
|
||||||
target: 'inpage',
|
target: INPAGE,
|
||||||
})
|
})
|
||||||
const extensionPort = extension.runtime.connect({ name: 'contentscript' })
|
const extensionPort = extension.runtime.connect({ name: CONTENT_SCRIPT })
|
||||||
const extensionStream = new PortStream(extensionPort)
|
const extensionStream = new PortStream(extensionPort)
|
||||||
|
|
||||||
// create and connect channel muxers
|
// create and connect channel muxers
|
||||||
@ -79,26 +67,26 @@ async function setupStreams() {
|
|||||||
pump(pageMux, pageStream, pageMux, (err) =>
|
pump(pageMux, pageStream, pageMux, (err) =>
|
||||||
logStreamDisconnectWarning('MetaMask Inpage Multiplex', err),
|
logStreamDisconnectWarning('MetaMask Inpage Multiplex', err),
|
||||||
)
|
)
|
||||||
pump(extensionMux, extensionStream, extensionMux, (err) =>
|
pump(extensionMux, extensionStream, extensionMux, (err) => {
|
||||||
logStreamDisconnectWarning('MetaMask Background Multiplex', err),
|
logStreamDisconnectWarning('MetaMask Background Multiplex', err)
|
||||||
)
|
notifyInpageOfStreamFailure()
|
||||||
|
})
|
||||||
|
|
||||||
// forward communication across inpage-background for these channels only
|
// forward communication across inpage-background for these channels only
|
||||||
forwardTrafficBetweenMuxers('provider', pageMux, extensionMux)
|
forwardTrafficBetweenMuxes(PROVIDER, pageMux, extensionMux)
|
||||||
forwardTrafficBetweenMuxers('publicConfig', pageMux, extensionMux)
|
|
||||||
|
|
||||||
// connect "phishing" channel to warning system
|
// connect "phishing" channel to warning system
|
||||||
const phishingStream = extensionMux.createStream('phishing')
|
const phishingStream = extensionMux.createStream('phishing')
|
||||||
phishingStream.once('data', redirectToPhishingWarning)
|
phishingStream.once('data', redirectToPhishingWarning)
|
||||||
}
|
}
|
||||||
|
|
||||||
function forwardTrafficBetweenMuxers(channelName, muxA, muxB) {
|
function forwardTrafficBetweenMuxes(channelName, muxA, muxB) {
|
||||||
const channelA = muxA.createStream(channelName)
|
const channelA = muxA.createStream(channelName)
|
||||||
const channelB = muxB.createStream(channelName)
|
const channelB = muxB.createStream(channelName)
|
||||||
pump(channelA, channelB, channelA, (err) =>
|
pump(channelA, channelB, channelA, (error) =>
|
||||||
logStreamDisconnectWarning(
|
console.debug(
|
||||||
`MetaMask muxed traffic for channel "${channelName}" failed.`,
|
`MetaMask muxed traffic for channel "${channelName}" failed.`,
|
||||||
err,
|
error,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -107,14 +95,35 @@ function forwardTrafficBetweenMuxers(channelName, muxA, muxB) {
|
|||||||
* Error handler for page to extension stream disconnections
|
* Error handler for page to extension stream disconnections
|
||||||
*
|
*
|
||||||
* @param {string} remoteLabel - Remote stream name
|
* @param {string} remoteLabel - Remote stream name
|
||||||
* @param {Error} err - Stream connection error
|
* @param {Error} error - Stream connection error
|
||||||
*/
|
*/
|
||||||
function logStreamDisconnectWarning(remoteLabel, err) {
|
function logStreamDisconnectWarning(remoteLabel, error) {
|
||||||
let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`
|
console.debug(
|
||||||
if (err) {
|
`MetaMask Contentscript: Lost connection to "${remoteLabel}".`,
|
||||||
warningMsg += `\n${err.stack}`
|
error,
|
||||||
}
|
)
|
||||||
console.warn(warningMsg)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function must ONLY be called in pump destruction/close callbacks.
|
||||||
|
* Notifies the inpage context that streams have failed, via window.postMessage.
|
||||||
|
* Relies on obj-multiplex and post-message-stream implementation details.
|
||||||
|
*/
|
||||||
|
function notifyInpageOfStreamFailure() {
|
||||||
|
window.postMessage(
|
||||||
|
{
|
||||||
|
target: INPAGE, // the post-message-stream "target"
|
||||||
|
data: {
|
||||||
|
// this object gets passed to obj-multiplex
|
||||||
|
name: PROVIDER, // the obj-multiplex channel name
|
||||||
|
data: {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: 'METAMASK_STREAM_FAILURE',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
window.location.origin,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,17 +230,3 @@ function redirectToPhishingWarning() {
|
|||||||
href: window.location.href,
|
href: window.location.href,
|
||||||
})}`
|
})}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a promise that resolves when the DOM is loaded (does not wait for images to load)
|
|
||||||
*/
|
|
||||||
async function domIsReady() {
|
|
||||||
// already loaded
|
|
||||||
if (['interactive', 'complete'].includes(document.readyState)) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
// wait for load
|
|
||||||
return new Promise((resolve) =>
|
|
||||||
window.addEventListener('DOMContentLoaded', resolve, { once: true }),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -19,10 +19,15 @@ export const CAVEAT_TYPES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const NOTIFICATION_NAMES = {
|
export const NOTIFICATION_NAMES = {
|
||||||
accountsChanged: 'wallet_accountsChanged',
|
accountsChanged: 'metamask_accountsChanged',
|
||||||
|
unlockStateChanged: 'metamask_unlockStateChanged',
|
||||||
|
chainChanged: 'metamask_chainChanged',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LOG_IGNORE_METHODS = ['wallet_sendDomainMetadata']
|
export const LOG_IGNORE_METHODS = [
|
||||||
|
'wallet_registerOnboarding',
|
||||||
|
'wallet_watchAsset',
|
||||||
|
]
|
||||||
|
|
||||||
export const LOG_METHOD_TYPES = {
|
export const LOG_METHOD_TYPES = {
|
||||||
restricted: 'restricted',
|
restricted: 'restricted',
|
||||||
@ -82,8 +87,9 @@ export const SAFE_METHODS = [
|
|||||||
'eth_submitWork',
|
'eth_submitWork',
|
||||||
'eth_syncing',
|
'eth_syncing',
|
||||||
'eth_uninstallFilter',
|
'eth_uninstallFilter',
|
||||||
'metamask_watchAsset',
|
|
||||||
'wallet_watchAsset',
|
|
||||||
'eth_getEncryptionPublicKey',
|
'eth_getEncryptionPublicKey',
|
||||||
'eth_decrypt',
|
'eth_decrypt',
|
||||||
|
'metamask_watchAsset',
|
||||||
|
'wallet_watchAsset',
|
||||||
|
'metamask_getProviderState',
|
||||||
]
|
]
|
||||||
|
@ -28,6 +28,7 @@ export class PermissionsController {
|
|||||||
getKeyringAccounts,
|
getKeyringAccounts,
|
||||||
getRestrictedMethods,
|
getRestrictedMethods,
|
||||||
getUnlockPromise,
|
getUnlockPromise,
|
||||||
|
isUnlocked,
|
||||||
notifyDomain,
|
notifyDomain,
|
||||||
notifyAllDomains,
|
notifyAllDomains,
|
||||||
preferences,
|
preferences,
|
||||||
@ -47,6 +48,7 @@ export class PermissionsController {
|
|||||||
this._notifyDomain = notifyDomain
|
this._notifyDomain = notifyDomain
|
||||||
this._notifyAllDomains = notifyAllDomains
|
this._notifyAllDomains = notifyAllDomains
|
||||||
this._showPermissionRequest = showPermissionRequest
|
this._showPermissionRequest = showPermissionRequest
|
||||||
|
this._isUnlocked = isUnlocked
|
||||||
|
|
||||||
this._restrictedMethods = getRestrictedMethods({
|
this._restrictedMethods = getRestrictedMethods({
|
||||||
getKeyringAccounts: this.getKeyringAccounts.bind(this),
|
getKeyringAccounts: this.getKeyringAccounts.bind(this),
|
||||||
@ -463,21 +465,20 @@ export class PermissionsController {
|
|||||||
throw new Error('Invalid accounts', newAccounts)
|
throw new Error('Invalid accounts', newAccounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._notifyDomain(origin, {
|
// We do not share accounts when the extension is locked.
|
||||||
method: NOTIFICATION_NAMES.accountsChanged,
|
if (this._isUnlocked()) {
|
||||||
result: newAccounts,
|
this._notifyDomain(origin, {
|
||||||
})
|
method: NOTIFICATION_NAMES.accountsChanged,
|
||||||
|
params: newAccounts,
|
||||||
// if the accounts changed from the perspective of the dapp,
|
})
|
||||||
// update "last seen" time for the origin and account(s)
|
this.permissionsLog.updateAccountsHistory(origin, newAccounts)
|
||||||
// exception: no accounts -> no times to update
|
}
|
||||||
this.permissionsLog.updateAccountsHistory(origin, newAccounts)
|
|
||||||
|
|
||||||
// NOTE:
|
// NOTE:
|
||||||
// we don't check for accounts changing in the notifyAllDomains case,
|
// We don't check for accounts changing in the notifyAllDomains case,
|
||||||
// because the log only records when accounts were last seen,
|
// because the log only records when accounts were last seen, and the
|
||||||
// and the accounts only change for all domains at once when permissions
|
// the accounts only change for all domains at once when permissions are
|
||||||
// are removed
|
// removed.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -508,9 +509,11 @@ export class PermissionsController {
|
|||||||
*/
|
*/
|
||||||
clearPermissions() {
|
clearPermissions() {
|
||||||
this.permissions.clearDomains()
|
this.permissions.clearDomains()
|
||||||
|
// It's safe to notify that no accounts are available, regardless of
|
||||||
|
// extension lock state
|
||||||
this._notifyAllDomains({
|
this._notifyAllDomains({
|
||||||
method: NOTIFICATION_NAMES.accountsChanged,
|
method: NOTIFICATION_NAMES.accountsChanged,
|
||||||
result: [],
|
params: [],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,7 +752,3 @@ export class PermissionsController {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addInternalMethodPrefix(method) {
|
|
||||||
return WALLET_PREFIX + method
|
|
||||||
}
|
|
||||||
|
@ -58,6 +58,7 @@ export default class PermissionsLogController {
|
|||||||
/**
|
/**
|
||||||
* Updates the exposed account history for the given origin.
|
* Updates the exposed account history for the given origin.
|
||||||
* Sets the 'last seen' time to Date.now() for the given accounts.
|
* Sets the 'last seen' time to Date.now() for the given accounts.
|
||||||
|
* Returns if the accounts array is empty.
|
||||||
*
|
*
|
||||||
* @param {string} origin - The origin that the accounts are exposed to.
|
* @param {string} origin - The origin that the accounts are exposed to.
|
||||||
* @param {Array<string>} accounts - The accounts.
|
* @param {Array<string>} accounts - The accounts.
|
||||||
|
@ -73,7 +73,7 @@ export default function createPermissionsMethodMiddleware({
|
|||||||
|
|
||||||
// custom method for getting metadata from the requesting domain,
|
// custom method for getting metadata from the requesting domain,
|
||||||
// sent automatically by the inpage provider when it's initialized
|
// sent automatically by the inpage provider when it's initialized
|
||||||
case 'wallet_sendDomainMetadata': {
|
case 'metamask_sendDomainMetadata': {
|
||||||
if (typeof req.domainMetadata?.name === 'string') {
|
if (typeof req.domainMetadata?.name === 'string') {
|
||||||
addDomainMetadata(req.origin, req.domainMetadata)
|
addDomainMetadata(req.origin, req.domainMetadata)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ cleanContextForImports()
|
|||||||
/* eslint-disable import/first */
|
/* eslint-disable import/first */
|
||||||
import log from 'loglevel'
|
import log from 'loglevel'
|
||||||
import LocalMessageDuplexStream from 'post-message-stream'
|
import LocalMessageDuplexStream from 'post-message-stream'
|
||||||
import { initProvider } from '@metamask/inpage-provider'
|
import { initializeProvider } from '@metamask/inpage-provider'
|
||||||
|
|
||||||
restoreContextAfterImports()
|
restoreContextAfterImports()
|
||||||
|
|
||||||
@ -45,10 +45,12 @@ log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn')
|
|||||||
|
|
||||||
// setup background connection
|
// setup background connection
|
||||||
const metamaskStream = new LocalMessageDuplexStream({
|
const metamaskStream = new LocalMessageDuplexStream({
|
||||||
name: 'inpage',
|
name: 'metamask-inpage',
|
||||||
target: 'contentscript',
|
target: 'metamask-contentscript',
|
||||||
})
|
})
|
||||||
|
|
||||||
initProvider({
|
initializeProvider({
|
||||||
connectionStream: metamaskStream,
|
connectionStream: metamaskStream,
|
||||||
|
logger: log,
|
||||||
|
shouldShimWeb3: true,
|
||||||
})
|
})
|
||||||
|
@ -23,6 +23,7 @@ const MESSAGE_TYPE = {
|
|||||||
ETH_GET_ENCRYPTION_PUBLIC_KEY: 'eth_getEncryptionPublicKey',
|
ETH_GET_ENCRYPTION_PUBLIC_KEY: 'eth_getEncryptionPublicKey',
|
||||||
ETH_SIGN: 'eth_sign',
|
ETH_SIGN: 'eth_sign',
|
||||||
ETH_SIGN_TYPED_DATA: 'eth_signTypedData',
|
ETH_SIGN_TYPED_DATA: 'eth_signTypedData',
|
||||||
|
GET_PROVIDER_STATE: 'metamask_getProviderState',
|
||||||
LOG_WEB3_SHIM_USAGE: 'metamask_logWeb3ShimUsage',
|
LOG_WEB3_SHIM_USAGE: 'metamask_logWeb3ShimUsage',
|
||||||
PERSONAL_SIGN: 'personal_sign',
|
PERSONAL_SIGN: 'personal_sign',
|
||||||
WATCH_ASSET: 'wallet_watchAsset',
|
WATCH_ASSET: 'wallet_watchAsset',
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import { MESSAGE_TYPE } from '../../enums'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This RPC method gets background state relevant to the provider.
|
||||||
|
* The background sends RPC notifications on state changes, but the provider
|
||||||
|
* first requests state on initialization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getProviderState = {
|
||||||
|
methodNames: [MESSAGE_TYPE.GET_PROVIDER_STATE],
|
||||||
|
implementation: getProviderStateHandler,
|
||||||
|
}
|
||||||
|
export default getProviderState
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ProviderStateHandlerResult
|
||||||
|
* @property {string} chainId - The current chain ID.
|
||||||
|
* @property {boolean} isUnlocked - Whether the extension is unlocked or not.
|
||||||
|
* @property {string} networkVersion - The current network ID.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ProviderStateHandlerOptions
|
||||||
|
* @property {() => ProviderStateHandlerResult} getProviderState - A function that
|
||||||
|
* gets the current provider state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('json-rpc-engine').JsonRpcRequest<[]>} req - The JSON-RPC request object.
|
||||||
|
* @param {import('json-rpc-engine').JsonRpcResponse<ProviderStateHandlerResult>} res - The JSON-RPC response object.
|
||||||
|
* @param {Function} _next - The json-rpc-engine 'next' callback.
|
||||||
|
* @param {Function} end - The json-rpc-engine 'end' callback.
|
||||||
|
* @param {ProviderStateHandlerOptions} options
|
||||||
|
*/
|
||||||
|
async function getProviderStateHandler(
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
_next,
|
||||||
|
end,
|
||||||
|
{ getProviderState: _getProviderState },
|
||||||
|
) {
|
||||||
|
res.result = {
|
||||||
|
...(await _getProviderState(req.origin)),
|
||||||
|
}
|
||||||
|
return end()
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
|
import getProviderState from './get-provider-state'
|
||||||
import logWeb3ShimUsage from './log-web3-shim-usage'
|
import logWeb3ShimUsage from './log-web3-shim-usage'
|
||||||
import watchAsset from './watch-asset'
|
import watchAsset from './watch-asset'
|
||||||
|
|
||||||
const handlers = [logWeb3ShimUsage, watchAsset]
|
const handlers = [getProviderState, logWeb3ShimUsage, watchAsset]
|
||||||
export default handlers
|
export default handlers
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import EventEmitter from 'events'
|
import EventEmitter from 'events'
|
||||||
|
|
||||||
import pump from 'pump'
|
import pump from 'pump'
|
||||||
import Dnode from 'dnode'
|
import Dnode from 'dnode'
|
||||||
import ObservableStore from 'obs-store'
|
|
||||||
import asStream from 'obs-store/lib/asStream'
|
|
||||||
import { JsonRpcEngine } from 'json-rpc-engine'
|
import { JsonRpcEngine } from 'json-rpc-engine'
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
import createEngineStream from 'json-rpc-middleware-stream/engineStream'
|
import createEngineStream from 'json-rpc-middleware-stream/engineStream'
|
||||||
@ -53,6 +50,7 @@ import TokenRatesController from './controllers/token-rates'
|
|||||||
import DetectTokensController from './controllers/detect-tokens'
|
import DetectTokensController from './controllers/detect-tokens'
|
||||||
import SwapsController from './controllers/swaps'
|
import SwapsController from './controllers/swaps'
|
||||||
import { PermissionsController } from './controllers/permissions'
|
import { PermissionsController } from './controllers/permissions'
|
||||||
|
import { NOTIFICATION_NAMES } from './controllers/permissions/enums'
|
||||||
import getRestrictedMethods from './controllers/permissions/restrictedMethods'
|
import getRestrictedMethods from './controllers/permissions/restrictedMethods'
|
||||||
import nodeify from './lib/nodeify'
|
import nodeify from './lib/nodeify'
|
||||||
import accountImporter from './account-import-strategies'
|
import accountImporter from './account-import-strategies'
|
||||||
@ -219,10 +217,11 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
initState: initState.KeyringController,
|
initState: initState.KeyringController,
|
||||||
encryptor: opts.encryptor || undefined,
|
encryptor: opts.encryptor || undefined,
|
||||||
})
|
})
|
||||||
this.keyringController.memStore.subscribe((s) =>
|
this.keyringController.memStore.subscribe((state) =>
|
||||||
this._onKeyringControllerUpdate(s),
|
this._onKeyringControllerUpdate(state),
|
||||||
)
|
)
|
||||||
this.keyringController.on('unlock', () => this.emit('unlock'))
|
this.keyringController.on('unlock', () => this.emit('unlock'))
|
||||||
|
this.keyringController.on('lock', () => this._onLock())
|
||||||
|
|
||||||
this.permissionsController = new PermissionsController(
|
this.permissionsController = new PermissionsController(
|
||||||
{
|
{
|
||||||
@ -233,6 +232,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
getUnlockPromise: this.appStateController.getUnlockPromise.bind(
|
getUnlockPromise: this.appStateController.getUnlockPromise.bind(
|
||||||
this.appStateController,
|
this.appStateController,
|
||||||
),
|
),
|
||||||
|
isUnlocked: this.isUnlocked.bind(this),
|
||||||
notifyDomain: this.notifyConnections.bind(this),
|
notifyDomain: this.notifyConnections.bind(this),
|
||||||
notifyAllDomains: this.notifyAllConnections.bind(this),
|
notifyAllDomains: this.notifyAllConnections.bind(this),
|
||||||
preferences: this.preferencesController.store,
|
preferences: this.preferencesController.store,
|
||||||
@ -348,6 +348,9 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
tokenRatesStore: this.tokenRatesController.store,
|
tokenRatesStore: this.tokenRatesController.store,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ensure isClientOpenAndUnlocked is updated when memState updates
|
||||||
|
this.on('update', (memState) => this._onStateUpdate(memState))
|
||||||
|
|
||||||
this.store.updateStructure({
|
this.store.updateStructure({
|
||||||
AppStateController: this.appStateController.store,
|
AppStateController: this.appStateController.store,
|
||||||
TransactionController: this.txController.store,
|
TransactionController: this.txController.store,
|
||||||
@ -450,38 +453,37 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor helper: initialize a public config store.
|
* Gets relevant state for the provider of an external origin.
|
||||||
* This store is used to make some config info available to Dapps synchronously.
|
*
|
||||||
|
* @param {string} origin - The origin to get the provider state for.
|
||||||
|
* @returns {Promise<{
|
||||||
|
* isUnlocked: boolean,
|
||||||
|
* networkVersion: string,
|
||||||
|
* chainId: string,
|
||||||
|
* accounts: string[],
|
||||||
|
* }>} An object with relevant state properties.
|
||||||
*/
|
*/
|
||||||
createPublicConfigStore() {
|
async getProviderState(origin) {
|
||||||
// subset of state for metamask inpage provider
|
return {
|
||||||
const publicConfigStore = new ObservableStore()
|
isUnlocked: this.isUnlocked(),
|
||||||
const { networkController } = this
|
...this.getProviderNetworkState(),
|
||||||
|
accounts: await this.permissionsController.getAccounts(origin),
|
||||||
// setup memStore subscription hooks
|
|
||||||
this.on('update', updatePublicConfigStore)
|
|
||||||
updatePublicConfigStore(this.getState())
|
|
||||||
|
|
||||||
publicConfigStore.destroy = () => {
|
|
||||||
this.removeEventListener &&
|
|
||||||
this.removeEventListener('update', updatePublicConfigStore)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updatePublicConfigStore(memState) {
|
/**
|
||||||
const chainId = networkController.getCurrentChainId()
|
* Gets network state relevant for external providers.
|
||||||
if (memState.network !== 'loading') {
|
*
|
||||||
publicConfigStore.putState(selectPublicState(chainId, memState))
|
* @param {Object} [memState] - The MetaMask memState. If not provided,
|
||||||
}
|
* this function will retrieve the most recent state.
|
||||||
|
* @returns {Object} An object with relevant network state properties.
|
||||||
|
*/
|
||||||
|
getProviderNetworkState(memState) {
|
||||||
|
const { network } = memState || this.getState()
|
||||||
|
return {
|
||||||
|
chainId: this.networkController.getCurrentChainId(),
|
||||||
|
networkVersion: network,
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPublicState(chainId, { isUnlocked, network }) {
|
|
||||||
return {
|
|
||||||
isUnlocked,
|
|
||||||
chainId,
|
|
||||||
networkVersion: network,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return publicConfigStore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -1813,8 +1815,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
const mux = setupMultiplex(connectionStream)
|
const mux = setupMultiplex(connectionStream)
|
||||||
|
|
||||||
// messages between inpage and background
|
// messages between inpage and background
|
||||||
this.setupProviderConnection(mux.createStream('provider'), sender)
|
this.setupProviderConnection(mux.createStream('metamask-provider'), sender)
|
||||||
this.setupPublicConfig(mux.createStream('publicConfig'))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1971,6 +1972,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
engine.push(
|
engine.push(
|
||||||
createMethodMiddleware({
|
createMethodMiddleware({
|
||||||
origin,
|
origin,
|
||||||
|
getProviderState: this.getProviderState.bind(this),
|
||||||
sendMetrics: this.metaMetricsController.trackEvent.bind(
|
sendMetrics: this.metaMetricsController.trackEvent.bind(
|
||||||
this.metaMetricsController,
|
this.metaMetricsController,
|
||||||
),
|
),
|
||||||
@ -1993,29 +1995,6 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
return engine
|
return engine
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A method for providing our public config info over a stream.
|
|
||||||
* This includes info we like to be synchronous if possible, like
|
|
||||||
* the current selected account, and network ID.
|
|
||||||
*
|
|
||||||
* Since synchronous methods have been deprecated in web3,
|
|
||||||
* this is a good candidate for deprecation.
|
|
||||||
*
|
|
||||||
* @param {*} outStream - The stream to provide public config over.
|
|
||||||
*/
|
|
||||||
setupPublicConfig(outStream) {
|
|
||||||
const configStore = this.createPublicConfigStore()
|
|
||||||
const configStream = asStream(configStore)
|
|
||||||
|
|
||||||
pump(configStream, outStream, (err) => {
|
|
||||||
configStore.destroy()
|
|
||||||
configStream.destroy()
|
|
||||||
if (err) {
|
|
||||||
log.error(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a reference to a connection by origin. Ignores the 'metamask' origin.
|
* Adds a reference to a connection by origin. Ignores the 'metamask' origin.
|
||||||
* Caller must ensure that the returned id is stored such that the reference
|
* Caller must ensure that the returned id is stored such that the reference
|
||||||
@ -2066,37 +2045,51 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Causes the RPC engines associated with the connections to the given origin
|
* Causes the RPC engines associated with the connections to the given origin
|
||||||
* to emit a notification event with the given payload.
|
* to emit a notification event with the given payload.
|
||||||
* Does nothing if the extension is locked or the origin is unknown.
|
*
|
||||||
|
* The caller is responsible for ensuring that only permitted notifications
|
||||||
|
* are sent.
|
||||||
|
*
|
||||||
|
* Ignores unknown origins.
|
||||||
*
|
*
|
||||||
* @param {string} origin - The connection's origin string.
|
* @param {string} origin - The connection's origin string.
|
||||||
* @param {any} payload - The event payload.
|
* @param {any} payload - The event payload.
|
||||||
*/
|
*/
|
||||||
notifyConnections(origin, payload) {
|
notifyConnections(origin, payload) {
|
||||||
const connections = this.connections[origin]
|
const connections = this.connections[origin]
|
||||||
if (!this.isUnlocked() || !connections) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.values(connections).forEach((conn) => {
|
if (connections) {
|
||||||
conn.engine && conn.engine.emit('notification', payload)
|
Object.values(connections).forEach((conn) => {
|
||||||
})
|
if (conn.engine) {
|
||||||
|
conn.engine.emit('notification', payload)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes the RPC engines associated with all connections to emit a
|
* Causes the RPC engines associated with all connections to emit a
|
||||||
* notification event with the given payload.
|
* notification event with the given payload.
|
||||||
* Does nothing if the extension is locked.
|
|
||||||
*
|
*
|
||||||
* @param {any} payload - The event payload.
|
* If the "payload" parameter is a function, the payload for each connection
|
||||||
|
* will be the return value of that function called with the connection's
|
||||||
|
* origin.
|
||||||
|
*
|
||||||
|
* The caller is responsible for ensuring that only permitted notifications
|
||||||
|
* are sent.
|
||||||
|
*
|
||||||
|
* @param {any} payload - The event payload, or payload getter function.
|
||||||
*/
|
*/
|
||||||
notifyAllConnections(payload) {
|
notifyAllConnections(payload) {
|
||||||
if (!this.isUnlocked()) {
|
const getPayload =
|
||||||
return
|
typeof payload === 'function'
|
||||||
}
|
? (origin) => payload(origin)
|
||||||
|
: () => payload
|
||||||
|
|
||||||
Object.values(this.connections).forEach((origin) => {
|
Object.values(this.connections).forEach((origin) => {
|
||||||
Object.values(origin).forEach((conn) => {
|
Object.values(origin).forEach((conn) => {
|
||||||
conn.engine && conn.engine.emit('notification', payload)
|
if (conn.engine) {
|
||||||
|
conn.engine.emit('notification', getPayload(origin))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2125,6 +2118,51 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.accountTracker.syncWithAddresses(addresses)
|
this.accountTracker.syncWithAddresses(addresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle global unlock, triggered by KeyringController unlock.
|
||||||
|
* Notifies all connections that the extension is unlocked.
|
||||||
|
*/
|
||||||
|
_onUnlock() {
|
||||||
|
this.notifyAllConnections((origin) => {
|
||||||
|
return {
|
||||||
|
method: NOTIFICATION_NAMES.unlockStateChanged,
|
||||||
|
params: {
|
||||||
|
isUnlocked: true,
|
||||||
|
accounts: this.permissionsController.getAccounts(origin),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.emit('unlock')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle global lock, triggered by KeyringController lock.
|
||||||
|
* Notifies all connections that the extension is locked.
|
||||||
|
*/
|
||||||
|
_onLock() {
|
||||||
|
this.notifyAllConnections({
|
||||||
|
method: NOTIFICATION_NAMES.unlockStateChanged,
|
||||||
|
params: {
|
||||||
|
isUnlocked: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.emit('lock')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle memory state updates.
|
||||||
|
* - Ensure isClientOpenAndUnlocked is updated
|
||||||
|
* - Notifies all connections with the new provider network state
|
||||||
|
* - The external providers handle diffing the state
|
||||||
|
*/
|
||||||
|
_onStateUpdate(newState) {
|
||||||
|
this.isClientOpenAndUnlocked = newState.isUnlocked && this._isClientOpen
|
||||||
|
this.notifyAllConnections({
|
||||||
|
method: NOTIFICATION_NAMES.chainChanged,
|
||||||
|
params: this.getProviderNetworkState(newState),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
"@metamask/eth-ledger-bridge-keyring": "^0.2.6",
|
"@metamask/eth-ledger-bridge-keyring": "^0.2.6",
|
||||||
"@metamask/eth-token-tracker": "^3.0.1",
|
"@metamask/eth-token-tracker": "^3.0.1",
|
||||||
"@metamask/etherscan-link": "^1.4.0",
|
"@metamask/etherscan-link": "^1.4.0",
|
||||||
"@metamask/inpage-provider": "^6.1.0",
|
"@metamask/inpage-provider": "^8.0.1",
|
||||||
"@metamask/jazzicon": "^2.0.0",
|
"@metamask/jazzicon": "^2.0.0",
|
||||||
"@metamask/logo": "^2.5.0",
|
"@metamask/logo": "^2.5.0",
|
||||||
"@popperjs/core": "^2.4.0",
|
"@popperjs/core": "^2.4.0",
|
||||||
|
@ -1022,7 +1022,7 @@ describe('MetaMaskController', function () {
|
|||||||
}
|
}
|
||||||
streamTest.write(
|
streamTest.write(
|
||||||
{
|
{
|
||||||
name: 'provider',
|
name: 'metamask-provider',
|
||||||
data: message,
|
data: message,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
@ -1061,7 +1061,7 @@ describe('MetaMaskController', function () {
|
|||||||
}
|
}
|
||||||
streamTest.write(
|
streamTest.write(
|
||||||
{
|
{
|
||||||
name: 'provider',
|
name: 'metamask-provider',
|
||||||
data: message,
|
data: message,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
|
@ -32,8 +32,6 @@ const keyringAccounts = deepFreeze([
|
|||||||
'0xcc74c7a59194e5d9268476955650d1e285be703c',
|
'0xcc74c7a59194e5d9268476955650d1e285be703c',
|
||||||
])
|
])
|
||||||
|
|
||||||
const getKeyringAccounts = async () => [...keyringAccounts]
|
|
||||||
|
|
||||||
const getIdentities = () => {
|
const getIdentities = () => {
|
||||||
return keyringAccounts.reduce((identities, address, index) => {
|
return keyringAccounts.reduce((identities, address, index) => {
|
||||||
identities[address] = { address, name: `Account ${index}` }
|
identities[address] = { address, name: `Account ${index}` }
|
||||||
@ -62,8 +60,6 @@ const getRestrictedMethods = (permController) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUnlockPromise = () => Promise.resolve()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets default mock constructor options for a permissions controller.
|
* Gets default mock constructor options for a permissions controller.
|
||||||
*
|
*
|
||||||
@ -71,10 +67,10 @@ const getUnlockPromise = () => Promise.resolve()
|
|||||||
*/
|
*/
|
||||||
export function getPermControllerOpts() {
|
export function getPermControllerOpts() {
|
||||||
return {
|
return {
|
||||||
showPermissionRequest: noop,
|
getKeyringAccounts: async () => [...keyringAccounts],
|
||||||
getKeyringAccounts,
|
getUnlockPromise: () => Promise.resolve(),
|
||||||
getUnlockPromise,
|
|
||||||
getRestrictedMethods,
|
getRestrictedMethods,
|
||||||
|
isUnlocked: () => true,
|
||||||
notifyDomain: noop,
|
notifyDomain: noop,
|
||||||
notifyAllDomains: noop,
|
notifyAllDomains: noop,
|
||||||
preferences: {
|
preferences: {
|
||||||
@ -86,6 +82,7 @@ export function getPermControllerOpts() {
|
|||||||
},
|
},
|
||||||
subscribe: noop,
|
subscribe: noop,
|
||||||
},
|
},
|
||||||
|
showPermissionRequest: noop,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +464,7 @@ export const getters = deepFreeze({
|
|||||||
removedAccounts: () => {
|
removedAccounts: () => {
|
||||||
return {
|
return {
|
||||||
method: NOTIFICATION_NAMES.accountsChanged,
|
method: NOTIFICATION_NAMES.accountsChanged,
|
||||||
result: [],
|
params: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -480,7 +477,7 @@ export const getters = deepFreeze({
|
|||||||
newAccounts: (accounts) => {
|
newAccounts: (accounts) => {
|
||||||
return {
|
return {
|
||||||
method: NOTIFICATION_NAMES.accountsChanged,
|
method: NOTIFICATION_NAMES.accountsChanged,
|
||||||
result: accounts,
|
params: accounts,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -586,17 +583,17 @@ export const getters = deepFreeze({
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a wallet_sendDomainMetadata RPC request object.
|
* Gets a metamask_sendDomainMetadata RPC request object.
|
||||||
*
|
*
|
||||||
* @param {string} origin - The origin of the request
|
* @param {string} origin - The origin of the request
|
||||||
* @param {Object} name - The domainMetadata name
|
* @param {Object} name - The domainMetadata name
|
||||||
* @param {Array<any>} [args] - Any other data for the request's domainMetadata
|
* @param {Array<any>} [args] - Any other data for the request's domainMetadata
|
||||||
* @returns {Object} An RPC request object
|
* @returns {Object} An RPC request object
|
||||||
*/
|
*/
|
||||||
wallet_sendDomainMetadata: (origin, name, ...args) => {
|
metamask_sendDomainMetadata: (origin, name, ...args) => {
|
||||||
return {
|
return {
|
||||||
origin,
|
origin,
|
||||||
method: 'wallet_sendDomainMetadata',
|
method: 'metamask_sendDomainMetadata',
|
||||||
domainMetadata: {
|
domainMetadata: {
|
||||||
...args,
|
...args,
|
||||||
name,
|
name,
|
||||||
|
@ -6,13 +6,9 @@ import sinon from 'sinon'
|
|||||||
import {
|
import {
|
||||||
METADATA_STORE_KEY,
|
METADATA_STORE_KEY,
|
||||||
METADATA_CACHE_MAX_SIZE,
|
METADATA_CACHE_MAX_SIZE,
|
||||||
WALLET_PREFIX,
|
|
||||||
} from '../../../../../app/scripts/controllers/permissions/enums'
|
} from '../../../../../app/scripts/controllers/permissions/enums'
|
||||||
|
|
||||||
import {
|
import { PermissionsController } from '../../../../../app/scripts/controllers/permissions'
|
||||||
PermissionsController,
|
|
||||||
addInternalMethodPrefix,
|
|
||||||
} from '../../../../../app/scripts/controllers/permissions'
|
|
||||||
|
|
||||||
import { getRequestUserApprovalHelper, grantPermissions } from './helpers'
|
import { getRequestUserApprovalHelper, grantPermissions } from './helpers'
|
||||||
|
|
||||||
@ -187,7 +183,7 @@ describe('permissions controller', function () {
|
|||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
notifications[origin],
|
notifications[origin],
|
||||||
[NOTIFICATIONS.removedAccounts()],
|
[NOTIFICATIONS.removedAccounts()],
|
||||||
'origin should have single wallet_accountsChanged:[] notification',
|
'origin should have single metamask_accountsChanged:[] notification',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1325,11 +1321,18 @@ describe('permissions controller', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('notifyAccountsChanged records history and sends notification', async function () {
|
it('notifyAccountsChanged records history and sends notification', async function () {
|
||||||
|
sinon.spy(permController, '_isUnlocked')
|
||||||
|
|
||||||
permController.notifyAccountsChanged(
|
permController.notifyAccountsChanged(
|
||||||
DOMAINS.a.origin,
|
DOMAINS.a.origin,
|
||||||
ACCOUNTS.a.permitted,
|
ACCOUNTS.a.permitted,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
permController._isUnlocked.calledOnce,
|
||||||
|
'_isUnlocked should have been called once',
|
||||||
|
)
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
permController.permissionsLog.updateAccountsHistory.calledOnce,
|
permController.permissionsLog.updateAccountsHistory.calledOnce,
|
||||||
'permissionsLog.updateAccountsHistory should have been called once',
|
'permissionsLog.updateAccountsHistory should have been called once',
|
||||||
@ -1342,6 +1345,25 @@ describe('permissions controller', function () {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('notifyAccountsChanged does nothing if _isUnlocked returns false', async function () {
|
||||||
|
permController._isUnlocked = sinon.fake.returns(false)
|
||||||
|
|
||||||
|
permController.notifyAccountsChanged(
|
||||||
|
DOMAINS.a.origin,
|
||||||
|
ACCOUNTS.a.permitted,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
permController._isUnlocked.calledOnce,
|
||||||
|
'_isUnlocked should have been called once',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
permController.permissionsLog.updateAccountsHistory.notCalled,
|
||||||
|
'permissionsLog.updateAccountsHistory should not have been called',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it('notifyAccountsChanged throws on invalid origin', async function () {
|
it('notifyAccountsChanged throws on invalid origin', async function () {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => permController.notifyAccountsChanged(4, ACCOUNTS.a.permitted),
|
() => permController.notifyAccountsChanged(4, ACCOUNTS.a.permitted),
|
||||||
@ -1604,11 +1626,5 @@ describe('permissions controller', function () {
|
|||||||
'pending approval origins should have expected item',
|
'pending approval origins should have expected item',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('addInternalMethodPrefix', function () {
|
|
||||||
const str = 'foo'
|
|
||||||
const res = addInternalMethodPrefix(str)
|
|
||||||
assert.equal(res, WALLET_PREFIX + str, 'should prefix correctly')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -286,7 +286,7 @@ describe('permissions log', function () {
|
|||||||
assert.equal(log.length, 0, 'log should be empty')
|
assert.equal(log.length, 0, 'log should be empty')
|
||||||
|
|
||||||
const res = { foo: 'bar' }
|
const res = { foo: 'bar' }
|
||||||
const req1 = RPC_REQUESTS.wallet_sendDomainMetadata(
|
const req1 = RPC_REQUESTS.metamask_sendDomainMetadata(
|
||||||
DOMAINS.c.origin,
|
DOMAINS.c.origin,
|
||||||
'foobar',
|
'foobar',
|
||||||
)
|
)
|
||||||
|
@ -808,7 +808,7 @@ describe('permissions middleware', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('wallet_sendDomainMetadata', function () {
|
describe('metamask_sendDomainMetadata', function () {
|
||||||
let permController, clock
|
let permController, clock
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@ -828,7 +828,10 @@ describe('permissions middleware', function () {
|
|||||||
DOMAINS.c.origin,
|
DOMAINS.c.origin,
|
||||||
)
|
)
|
||||||
|
|
||||||
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
const req = RPC_REQUESTS.metamask_sendDomainMetadata(
|
||||||
|
DOMAINS.c.origin,
|
||||||
|
name,
|
||||||
|
)
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
||||||
@ -861,7 +864,10 @@ describe('permissions middleware', function () {
|
|||||||
extensionId,
|
extensionId,
|
||||||
)
|
)
|
||||||
|
|
||||||
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
const req = RPC_REQUESTS.metamask_sendDomainMetadata(
|
||||||
|
DOMAINS.c.origin,
|
||||||
|
name,
|
||||||
|
)
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
||||||
@ -885,7 +891,10 @@ describe('permissions middleware', function () {
|
|||||||
DOMAINS.c.origin,
|
DOMAINS.c.origin,
|
||||||
)
|
)
|
||||||
|
|
||||||
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin, name)
|
const req = RPC_REQUESTS.metamask_sendDomainMetadata(
|
||||||
|
DOMAINS.c.origin,
|
||||||
|
name,
|
||||||
|
)
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
await assert.doesNotReject(cMiddleware(req, res), 'should not reject')
|
||||||
@ -907,7 +916,7 @@ describe('permissions middleware', function () {
|
|||||||
DOMAINS.c.origin,
|
DOMAINS.c.origin,
|
||||||
)
|
)
|
||||||
|
|
||||||
const req = RPC_REQUESTS.wallet_sendDomainMetadata(DOMAINS.c.origin)
|
const req = RPC_REQUESTS.metamask_sendDomainMetadata(DOMAINS.c.origin)
|
||||||
delete req.domainMetadata
|
delete req.domainMetadata
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
|
24
yarn.lock
24
yarn.lock
@ -2115,20 +2115,19 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@metamask/forwarder/-/forwarder-1.1.0.tgz#13829d8244bbf19ea658c0b20d21a77b67de0bdd"
|
resolved "https://registry.yarnpkg.com/@metamask/forwarder/-/forwarder-1.1.0.tgz#13829d8244bbf19ea658c0b20d21a77b67de0bdd"
|
||||||
integrity sha512-Hggj4y0QIjDzKGTXzarhEPIQyFSB2bi2y6YLJNwaT4JmP30UB5Cj6gqoY0M4pj3QT57fzp0BUuGp7F/AUe28tw==
|
integrity sha512-Hggj4y0QIjDzKGTXzarhEPIQyFSB2bi2y6YLJNwaT4JmP30UB5Cj6gqoY0M4pj3QT57fzp0BUuGp7F/AUe28tw==
|
||||||
|
|
||||||
"@metamask/inpage-provider@^6.1.0":
|
"@metamask/inpage-provider@^8.0.1":
|
||||||
version "6.3.0"
|
version "8.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@metamask/inpage-provider/-/inpage-provider-6.3.0.tgz#92d965e20912c24adbf973efbd07dbf339547741"
|
resolved "https://registry.yarnpkg.com/@metamask/inpage-provider/-/inpage-provider-8.0.1.tgz#67b1f0733ae7c0e0e429dc5c067ba9d2dd6d66da"
|
||||||
integrity sha512-n7E06+8hWdYKmgJo84WFvgX6/BSqaOQEOMIrcbrP48LdkkZNEAChx6D8oUb2lYDQiWgahR+f20jsJoN4WmOjxw==
|
integrity sha512-dN3IpiJtaHeiPzF01UXnrQ6TxXbXbkU54kiOHuIUe9e8s7vyPzgDgN2nj84xjmIkqxL0MKY90Wcp0obFKnNj+Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
eth-rpc-errors "^2.1.1"
|
"@metamask/safe-event-emitter" "^2.0.0"
|
||||||
|
eth-rpc-errors "^4.0.2"
|
||||||
fast-deep-equal "^2.0.1"
|
fast-deep-equal "^2.0.1"
|
||||||
is-stream "^2.0.0"
|
is-stream "^2.0.0"
|
||||||
json-rpc-engine "^5.2.0"
|
json-rpc-engine "^6.1.0"
|
||||||
json-rpc-middleware-stream "^2.1.1"
|
json-rpc-middleware-stream "^2.1.1"
|
||||||
obj-multiplex "^1.0.0"
|
obj-multiplex "^1.0.0"
|
||||||
obs-store "^4.0.3"
|
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
safe-event-emitter "^1.0.1"
|
|
||||||
|
|
||||||
"@metamask/jazzicon@^2.0.0":
|
"@metamask/jazzicon@^2.0.0":
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@ -9889,13 +9888,6 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
|
|||||||
json-rpc-random-id "^1.0.0"
|
json-rpc-random-id "^1.0.0"
|
||||||
xtend "^4.0.1"
|
xtend "^4.0.1"
|
||||||
|
|
||||||
eth-rpc-errors@^2.1.1:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-2.1.1.tgz#00a7d6c8a9c864a8ab7d0356be20964e5bee4b13"
|
|
||||||
integrity sha512-MY3zAa5ZF8hvgQu1HOF9agaK5GgigBRGpTJ8H0oVlE0NqMu13CW6syyjLXdeIDCGQTbUeHliU1z9dVmvMKx1Tg==
|
|
||||||
dependencies:
|
|
||||||
fast-safe-stringify "^2.0.6"
|
|
||||||
|
|
||||||
eth-rpc-errors@^3.0.0:
|
eth-rpc-errors@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10"
|
resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10"
|
||||||
@ -15221,7 +15213,7 @@ json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0:
|
|||||||
promise-to-callback "^1.0.0"
|
promise-to-callback "^1.0.0"
|
||||||
safe-event-emitter "^1.0.1"
|
safe-event-emitter "^1.0.1"
|
||||||
|
|
||||||
json-rpc-engine@^5.2.0, json-rpc-engine@^5.3.0:
|
json-rpc-engine@^5.3.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.3.0.tgz#7dc7291766b28766ebda33eb6d3f4c6301c44ff4"
|
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.3.0.tgz#7dc7291766b28766ebda33eb6d3f4c6301c44ff4"
|
||||||
integrity sha512-+diJ9s8rxB+fbJhT7ZEf8r8spaLRignLd8jTgQ/h5JSGppAHGtNMZtCoabipCaleR1B3GTGxbXBOqhaJSGmPGQ==
|
integrity sha512-+diJ9s8rxB+fbJhT7ZEf8r8spaLRignLd8jTgQ/h5JSGppAHGtNMZtCoabipCaleR1B3GTGxbXBOqhaJSGmPGQ==
|
||||||
|
Loading…
Reference in New Issue
Block a user