mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Restore support for @metamask/inpage provider@"< 8.0.0" (#10179)
This restores support for versions of the inpage provider prior to v8. This is intended to support dapps and extensions that directly instantiated their own provider rather than using the injected provider. * Forward traffic between old and new provider streams * Ignore publicConfig stream for non-legacy muxes * Transform accountsChanged notification for legacy streams * Convert publicConfigStore to singleton Co-authored-by: Mark Stacey <markjstacey@gmail.com>
This commit is contained in:
parent
849a47afba
commit
0dfdd44ae7
@ -4,6 +4,7 @@ import LocalMessageDuplexStream from 'post-message-stream'
|
||||
import ObjectMultiplex from 'obj-multiplex'
|
||||
import extension from 'extensionizer'
|
||||
import PortStream from 'extension-port-stream'
|
||||
import { obj as createThoughStream } from 'through2'
|
||||
|
||||
// These require calls need to use require to be statically recognized by browserify
|
||||
const fs = require('fs')
|
||||
@ -20,6 +21,12 @@ const CONTENT_SCRIPT = 'metamask-contentscript'
|
||||
const INPAGE = 'metamask-inpage'
|
||||
const PROVIDER = 'metamask-provider'
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
const LEGACY_CONTENT_SCRIPT = 'contentscript'
|
||||
const LEGACY_INPAGE = 'inpage'
|
||||
const LEGACY_PROVIDER = 'provider'
|
||||
const LEGACY_PUBLIC_CONFIG = 'publicConfig'
|
||||
|
||||
if (shouldInjectProvider()) {
|
||||
injectScript(inpageBundle)
|
||||
setupStreams()
|
||||
@ -63,6 +70,7 @@ async function setupStreams() {
|
||||
pageMux.setMaxListeners(25)
|
||||
const extensionMux = new ObjectMultiplex()
|
||||
extensionMux.setMaxListeners(25)
|
||||
extensionMux.ignoreStream(LEGACY_PUBLIC_CONFIG) // TODO:LegacyProvider: Delete
|
||||
|
||||
pump(pageMux, pageStream, pageMux, (err) =>
|
||||
logStreamDisconnectWarning('MetaMask Inpage Multiplex', err),
|
||||
@ -78,6 +86,44 @@ async function setupStreams() {
|
||||
// connect "phishing" channel to warning system
|
||||
const phishingStream = extensionMux.createStream('phishing')
|
||||
phishingStream.once('data', redirectToPhishingWarning)
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
// handle legacy provider
|
||||
const legacyPageStream = new LocalMessageDuplexStream({
|
||||
name: LEGACY_CONTENT_SCRIPT,
|
||||
target: LEGACY_INPAGE,
|
||||
})
|
||||
|
||||
const legacyPageMux = new ObjectMultiplex()
|
||||
legacyPageMux.setMaxListeners(25)
|
||||
const legacyExtensionMux = new ObjectMultiplex()
|
||||
legacyExtensionMux.setMaxListeners(25)
|
||||
|
||||
pump(legacyPageMux, legacyPageStream, legacyPageMux, (err) =>
|
||||
logStreamDisconnectWarning('MetaMask Legacy Inpage Multiplex', err),
|
||||
)
|
||||
pump(
|
||||
legacyExtensionMux,
|
||||
extensionStream,
|
||||
getNotificationTransformStream(),
|
||||
legacyExtensionMux,
|
||||
(err) => {
|
||||
logStreamDisconnectWarning('MetaMask Background Legacy Multiplex', err)
|
||||
notifyInpageOfStreamFailure()
|
||||
},
|
||||
)
|
||||
|
||||
forwardNamedTrafficBetweenMuxes(
|
||||
LEGACY_PROVIDER,
|
||||
PROVIDER,
|
||||
legacyPageMux,
|
||||
legacyExtensionMux,
|
||||
)
|
||||
forwardTrafficBetweenMuxes(
|
||||
LEGACY_PUBLIC_CONFIG,
|
||||
legacyPageMux,
|
||||
legacyExtensionMux,
|
||||
)
|
||||
}
|
||||
|
||||
function forwardTrafficBetweenMuxes(channelName, muxA, muxB) {
|
||||
@ -91,6 +137,37 @@ function forwardTrafficBetweenMuxes(channelName, muxA, muxB) {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
function forwardNamedTrafficBetweenMuxes(
|
||||
channelAName,
|
||||
channelBName,
|
||||
muxA,
|
||||
muxB,
|
||||
) {
|
||||
const channelA = muxA.createStream(channelAName)
|
||||
const channelB = muxB.createStream(channelBName)
|
||||
pump(channelA, channelB, channelA, (error) =>
|
||||
console.debug(
|
||||
`MetaMask: Muxed traffic between channels "${channelAName}" and "${channelBName}" failed.`,
|
||||
error,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
function getNotificationTransformStream() {
|
||||
return createThoughStream((chunk, _, cb) => {
|
||||
if (chunk?.name === PROVIDER) {
|
||||
if (chunk.data?.method === 'metamask_accountsChanged') {
|
||||
chunk.data.method = 'wallet_accountsChanged'
|
||||
chunk.data.result = chunk.data.params
|
||||
delete chunk.data.params
|
||||
}
|
||||
}
|
||||
cb(null, chunk)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler for page to extension stream disconnections
|
||||
*
|
||||
|
@ -1,6 +1,8 @@
|
||||
import EventEmitter from 'events'
|
||||
import pump from 'pump'
|
||||
import Dnode from 'dnode'
|
||||
import { ObservableStore } from '@metamask/obs-store'
|
||||
import { storeAsStream } from '@metamask/obs-store/dist/asStream'
|
||||
import { JsonRpcEngine } from 'json-rpc-engine'
|
||||
import { debounce } from 'lodash'
|
||||
import createEngineStream from 'json-rpc-middleware-stream/engineStream'
|
||||
@ -413,6 +415,9 @@ export default class MetamaskController extends EventEmitter {
|
||||
) {
|
||||
this.submitPassword(password)
|
||||
}
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
this.publicConfigStore = this.createPublicConfigStore()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -459,6 +464,38 @@ export default class MetamaskController extends EventEmitter {
|
||||
return providerProxy
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:LegacyProvider: Delete
|
||||
* Constructor helper: initialize a public config store.
|
||||
* This store is used to make some config info available to Dapps synchronously.
|
||||
*/
|
||||
createPublicConfigStore() {
|
||||
// subset of state for metamask inpage provider
|
||||
const publicConfigStore = new ObservableStore()
|
||||
const { networkController } = this
|
||||
|
||||
// setup memStore subscription hooks
|
||||
this.on('update', updatePublicConfigStore)
|
||||
updatePublicConfigStore(this.getState())
|
||||
|
||||
function updatePublicConfigStore(memState) {
|
||||
const chainId = networkController.getCurrentChainId()
|
||||
if (memState.network !== 'loading') {
|
||||
publicConfigStore.putState(selectPublicState(chainId, memState))
|
||||
}
|
||||
}
|
||||
|
||||
function selectPublicState(chainId, { isUnlocked, network }) {
|
||||
return {
|
||||
isUnlocked,
|
||||
chainId,
|
||||
networkVersion: network,
|
||||
}
|
||||
}
|
||||
|
||||
return publicConfigStore
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets relevant state for the provider of an external origin.
|
||||
*
|
||||
@ -1831,6 +1868,10 @@ export default class MetamaskController extends EventEmitter {
|
||||
|
||||
// messages between inpage and background
|
||||
this.setupProviderConnection(mux.createStream('metamask-provider'), sender)
|
||||
|
||||
// TODO:LegacyProvider: Delete
|
||||
// legacy streams
|
||||
this.setupPublicConfig(mux.createStream('publicConfig'))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2016,6 +2057,28 @@ export default class MetamaskController extends EventEmitter {
|
||||
return engine
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:LegacyProvider: Delete
|
||||
* 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 configStream = storeAsStream(this.publicConfigStore)
|
||||
|
||||
pump(configStream, outStream, (err) => {
|
||||
configStream.destroy()
|
||||
if (err) {
|
||||
log.error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user