diff --git a/.depcheckrc.yml b/.depcheckrc.yml index d9fcf63e61e..8b18d8ba890 100644 --- a/.depcheckrc.yml +++ b/.depcheckrc.yml @@ -1,6 +1,7 @@ # List things here that *are - 'used, that depcheck is wrong about' ignores: - '@metamask/oss-attribution-generator' + - 'webpack-cli' # Note: Everything below this line should be removed after investigation # TODO: Investigate each dependency to see whether it's used diff --git a/.eslintignore b/.eslintignore index f6612bc3557..dd39d345bd8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ +/scripts/inpage-bridge /app/core/InpageBridgeWeb3.js /app/util/blockies.js __snapshots__ diff --git a/.gitignore b/.gitignore index cb9d63a3ee8..2776fe0c77f 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ buck-out/ tests # app-specific +/scripts/inpage-bridge/dist /android/app/src/main/assets/InpageBridgeWeb3.js /app/core/InpageBridgeWeb3.js diff --git a/app/util/streams.js b/app/util/streams.js index 9c2538c0879..1130d58a6d3 100644 --- a/app/util/streams.js +++ b/app/util/streams.js @@ -1,6 +1,6 @@ /* eslint-disable import/no-commonjs */ const Through = require('through2'); -const ObjectMultiplex = require('obj-multiplex'); +const ObjectMultiplex = require('@metamask/object-multiplex'); const pump = require('pump'); /** diff --git a/package.json b/package.json index 91e2cf05370..5b792f7979b 100644 --- a/package.json +++ b/package.json @@ -251,7 +251,6 @@ "metro-config": "^0.71.1", "multihashes": "0.4.14", "number-to-bn": "1.7.0", - "obj-multiplex": "1.0.0", "obs-store": "4.0.3", "path": "0.12.7", "pbkdf2": "3.1.2", @@ -325,7 +324,7 @@ "react-native-webview": "11.13.0", "react-native-webview-invoke": "^0.6.2", "react-redux": "7.2.4", - "readable-stream": "1.0.33", + "readable-stream": "2.3.7", "redux": "4.1.1", "redux-mock-store": "1.5.4", "redux-persist": "6.0.0", @@ -335,7 +334,7 @@ "reselect": "^4.0.0", "rn-fetch-blob": "^0.12.0", "socket.io-client": "^4.5.3", - "stream-browserify": "1.0.0", + "stream-browserify": "3.0.0", "through2": "3.0.1", "unicode-confusables": "^0.1.1", "url": "0.11.0", @@ -359,7 +358,9 @@ "@metamask/eslint-config": "^9.0.0", "@metamask/eslint-config-typescript": "^9.0.0", "@metamask/mobile-provider": "^3.0.0", + "@metamask/object-multiplex": "^1.1.0", "@metamask/oss-attribution-generator": "^2.0.1", + "@metamask/providers": "^13.0.0", "@metamask/test-dapp": "^7.1.0", "@react-native-community/datetimepicker": "^7.5.0", "@react-native-community/eslint-config": "^2.0.0", @@ -468,6 +469,8 @@ "ts-node": "^10.5.0", "typescript": "~4.8.4", "wdio-cucumberjs-json-reporter": "^4.4.3", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4", "xml2js": "^0.5.0", "yarn-deduplicate": "^6.0.2" }, diff --git a/scripts/build-inpage-bridge.sh b/scripts/build-inpage-bridge.sh new file mode 100755 index 00000000000..7823e49dd80 --- /dev/null +++ b/scripts/build-inpage-bridge.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail + +rm -f app/core/InpageBridgeWeb3.js +mkdir -p scripts/inpage-bridge/dist && rm -rf scripts/inpage-bridge/dist/* +cd scripts/inpage-bridge/inpage +../../../node_modules/.bin/webpack --config webpack.config.js +cd .. +node content-script/build.js +cat dist/inpage-bundle.js content-script/index.js > dist/index-raw.js +../../node_modules/.bin/webpack --config webpack.config.js +cd ../.. +cp scripts/inpage-bridge/dist/index.js app/core/InpageBridgeWeb3.js diff --git a/scripts/build.sh b/scripts/build.sh index 819360b2c7a..db239a3e8fb 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -109,7 +109,6 @@ checkParameters(){ prebuild(){ # Import provider - cp node_modules/@metamask/mobile-provider/dist/index.js app/core/InpageBridgeWeb3.js yarn --ignore-engines build:static-logos # Load JS specific env variables diff --git a/scripts/inpage-bridge/content-script/build.js b/scripts/inpage-bridge/content-script/build.js new file mode 100644 index 00000000000..cd0ca95605c --- /dev/null +++ b/scripts/inpage-bridge/content-script/build.js @@ -0,0 +1,14 @@ +const fs = require('fs'); +const path = require('path'); + +const distPath = path.join(__dirname, '..', '/', 'dist'); + +const inpageContent = fs + .readFileSync(path.join(distPath, 'inpage-content.js')) + .toString(); + +// wrap the inpage content in a variable declaration +const code = `const inpageBundle = ${JSON.stringify(inpageContent)}`; + +fs.writeFileSync(path.join(distPath, 'inpage-bundle.js'), code, 'ascii'); +console.log('content-script.js generated succesfully'); diff --git a/scripts/inpage-bridge/content-script/index.js b/scripts/inpage-bridge/content-script/index.js new file mode 100644 index 00000000000..9cf37e70a94 --- /dev/null +++ b/scripts/inpage-bridge/content-script/index.js @@ -0,0 +1,147 @@ +/* global inpageBundle */ + +if (shouldInject()) { + injectScript(inpageBundle); + start(); +} + +// Functions + +/** + * Sets up the stream communication and submits site metadata + * + */ +async function start() { + await domIsReady(); + window._metamaskSetupProvider(); +} + +/** + * Injects a script tag into the current document + * + * @param {string} content - Code to be executed in the current document + */ +function injectScript(content) { + try { + const container = document.head || document.documentElement; + + // synchronously execute script in page context + const scriptTag = document.createElement('script'); + scriptTag.setAttribute('async', false); + scriptTag.textContent = content; + container.insertBefore(scriptTag, container.children[0]); + + // script executed; remove script element from DOM + container.removeChild(scriptTag); + } catch (err) { + console.error('MetaMask script injection failed', err); + } +} + +/** + * Determines if the provider should be injected. + * + * @returns {boolean} {@code true} if the provider should be injected. + */ +function shouldInject() { + return ( + doctypeCheck() && + suffixCheck() && + documentElementCheck() && + !blockedDomainCheck() + ); +} + +/** + * Checks the doctype of the current document if it exists + * + * @returns {boolean} {@code true} if the doctype is html or if none exists + */ +function doctypeCheck() { + const { doctype } = window.document; + if (doctype) { + return doctype.name === 'html'; + } + return true; +} + +/** + * Returns whether or not the extension (suffix) of the current document is + * prohibited. + * + * This checks {@code window.location.pathname} against a set of file extensions + * that should not have the provider injected into them. This check is indifferent + * of query parameters in the location. + * + * @returns {boolean} whether or not the extension of the current document is prohibited + */ +function suffixCheck() { + const prohibitedTypes = [/\\.xml$/u, /\\.pdf$/u]; + const currentUrl = window.location.pathname; + for (let i = 0; i < prohibitedTypes.length; i++) { + if (prohibitedTypes[i].test(currentUrl)) { + return false; + } + } + return true; +} + +/** + * Checks the documentElement of the current document + * + * @returns {boolean} {@code true} if the documentElement is an html node or if none exists + */ +function documentElementCheck() { + const documentElement = document.documentElement.nodeName; + if (documentElement) { + return documentElement.toLowerCase() === 'html'; + } + return true; +} + +/** + * Checks if the current domain is blocked + * + * @returns {boolean} {@code true} if the current domain is blocked + */ +function blockedDomainCheck() { + const blockedDomains = [ + 'uscourts.gov', + 'dropbox.com', + 'webbyawards.com', + 'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html', + 'adyen.com', + 'gravityforms.com', + 'harbourair.com', + 'ani.gamer.com.tw', + 'blueskybooking.com', + 'sharefile.com', + ]; + const currentUrl = window.location.href; + let currentRegex; + for (let i = 0; i < blockedDomains.length; i++) { + const blockedDomain = blockedDomains[i].replace('.', '\\.'); + currentRegex = new RegExp( + `(?:https?:\\/\\/)(?:(?!${blockedDomain}).)*$`, + 'u', + ); + if (!currentRegex.test(currentUrl)) { + return true; + } + } + return false; +} + +/** + * 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; + } + // wait for load + await new Promise((resolve) => + window.addEventListener('DOMContentLoaded', resolve, { once: true }), + ); +} diff --git a/scripts/inpage-bridge/inpage/MobilePortStream.js b/scripts/inpage-bridge/inpage/MobilePortStream.js new file mode 100644 index 00000000000..7c538ae6397 --- /dev/null +++ b/scripts/inpage-bridge/inpage/MobilePortStream.js @@ -0,0 +1,109 @@ +const { inherits } = require('util'); +const { Duplex } = require('readable-stream'); + +const noop = () => undefined; + +module.exports = MobilePortStream; + +inherits(MobilePortStream, Duplex); + +/** + * Creates a stream that's both readable and writable. + * The stream supports arbitrary objects. + * + * @class + * @param {Object} port Remote Port object + */ +function MobilePortStream(port) { + Duplex.call(this, { + objectMode: true, + }); + this._name = port.name; + this._targetWindow = window; + this._port = port; + this._origin = location.origin; + window.addEventListener('message', this._onMessage.bind(this), false); +} + +/** + * Callback triggered when a message is received from + * the remote Port associated with this Stream. + * + * @private + * @param {Object} msg - Payload from the onMessage listener of Port + */ +MobilePortStream.prototype._onMessage = function (event) { + const msg = event.data; + + // validate message + if (this._origin !== '*' && event.origin !== this._origin) { + return; + } + if (!msg || typeof msg !== 'object') { + return; + } + if (!msg.data || typeof msg.data !== 'object') { + return; + } + if (msg.target && msg.target !== this._name) { + return; + } + // Filter outgoing messages + if (msg.data.data && msg.data.data.toNative) { + return; + } + + if (Buffer.isBuffer(msg)) { + delete msg._isBuffer; + const data = Buffer.from(msg); + this.push(data); + } else { + this.push(msg); + } +}; + +/** + * Callback triggered when the remote Port + * associated with this Stream disconnects. + * + * @private + */ +MobilePortStream.prototype._onDisconnect = function () { + this.destroy(); +}; + +/** + * Explicitly sets read operations to a no-op + */ +MobilePortStream.prototype._read = noop; + +/** + * Called internally when data should be written to + * this writable stream. + * + * @private + * @param {*} msg Arbitrary object to write + * @param {string} encoding Encoding to use when writing payload + * @param {Function} cb Called when writing is complete or an error occurs + */ +MobilePortStream.prototype._write = function (msg, _encoding, cb) { + try { + if (Buffer.isBuffer(msg)) { + const data = msg.toJSON(); + data._isBuffer = true; + window.ReactNativeWebView.postMessage( + JSON.stringify({ ...data, origin: window.location.href }), + ); + } else { + if (msg.data) { + msg.data.toNative = true; + } + window.ReactNativeWebView.postMessage( + JSON.stringify({ ...msg, origin: window.location.href }), + ); + } + } catch (err) { + return cb(new Error('MobilePortStream - disconnected')); + } + return cb(); +}; diff --git a/scripts/inpage-bridge/inpage/ReactNativePostMessageStream.js b/scripts/inpage-bridge/inpage/ReactNativePostMessageStream.js new file mode 100644 index 00000000000..3891d41da97 --- /dev/null +++ b/scripts/inpage-bridge/inpage/ReactNativePostMessageStream.js @@ -0,0 +1,80 @@ +const { inherits } = require('util'); +const { Duplex } = require('readable-stream'); + +const noop = () => undefined; + +module.exports = PostMessageStream; + +inherits(PostMessageStream, Duplex); + +function PostMessageStream(opts) { + Duplex.call(this, { + objectMode: true, + }); + + this._name = opts.name; + this._target = opts.target; + this._targetWindow = opts.targetWindow || window; + this._origin = opts.targetWindow ? '*' : location.origin; + + // initialization flags + this._init = false; + this._haveSyn = false; + + window.addEventListener('message', this._onMessage.bind(this), false); + // send syncorization message + this._write('SYN', null, noop); + this.cork(); +} + +// private +PostMessageStream.prototype._onMessage = function (event) { + const msg = event.data; + + // validate message + if (this._origin !== '*' && event.origin !== this._origin) { + return; + } + if (event.source !== this._targetWindow && window === top) { + return; + } + if (!msg || typeof msg !== 'object') { + return; + } + if (msg.target !== this._name) { + return; + } + if (!msg.data) { + return; + } + + if (this._init) { + // forward message + try { + this.push(msg.data); + } catch (err) { + this.emit('error', err); + } + } else if (msg.data === 'SYN') { + this._haveSyn = true; + this._write('ACK', null, noop); + } else if (msg.data === 'ACK') { + this._init = true; + if (!this._haveSyn) { + this._write('ACK', null, noop); + } + this.uncork(); + } +}; + +// stream plumbing +PostMessageStream.prototype._read = noop; + +PostMessageStream.prototype._write = function (data, _encoding, cb) { + const message = { + target: this._target, + data, + }; + this._targetWindow.postMessage(message, this._origin); + cb(); +}; diff --git a/scripts/inpage-bridge/inpage/index.js b/scripts/inpage-bridge/inpage/index.js new file mode 100644 index 00000000000..c6aa65f8651 --- /dev/null +++ b/scripts/inpage-bridge/inpage/index.js @@ -0,0 +1,125 @@ +const { initializeProvider, shimWeb3 } = require('@metamask/providers'); +const ObjectMultiplex = require('@metamask/object-multiplex'); +const pump = require('pump'); +const MobilePortStream = require('./MobilePortStream'); +const ReactNativePostMessageStream = require('./ReactNativePostMessageStream'); + +const INPAGE = 'metamask-inpage'; +const CONTENT_SCRIPT = 'metamask-contentscript'; +const PROVIDER = 'metamask-provider'; + +// Setup stream for content script communication +const metamaskStream = new ReactNativePostMessageStream({ + name: INPAGE, + target: CONTENT_SCRIPT, +}); + +// Initialize provider object (window.ethereum) +initializeProvider({ + connectionStream: metamaskStream, + shouldSendMetadata: false, +}); + +// Set content script post-setup function +Object.defineProperty(window, '_metamaskSetupProvider', { + value: () => { + setupProviderStreams(); + delete window._metamaskSetupProvider; + }, + configurable: true, + enumerable: false, + writable: false, +}); + +// Functions + +/** + * Setup function called from content script after the DOM is ready. + */ +function setupProviderStreams() { + // the transport-specific streams for communication between inpage and background + const pageStream = new ReactNativePostMessageStream({ + name: CONTENT_SCRIPT, + target: INPAGE, + }); + + const appStream = new MobilePortStream({ + name: CONTENT_SCRIPT, + }); + + // create and connect channel muxes + // so we can handle the channels individually + const pageMux = new ObjectMultiplex(); + pageMux.setMaxListeners(25); + const appMux = new ObjectMultiplex(); + appMux.setMaxListeners(25); + + pump(pageMux, pageStream, pageMux, (err) => + logStreamDisconnectWarning('MetaMask Inpage Multiplex', err), + ); + pump(appMux, appStream, appMux, (err) => { + logStreamDisconnectWarning('MetaMask Background Multiplex', err); + notifyProviderOfStreamFailure(); + }); + + // forward communication across inpage-background for these channels only + forwardTrafficBetweenMuxes(PROVIDER, pageMux, appMux); + + // add web3 shim + shimWeb3(window.ethereum); +} + +/** + * Set up two-way communication between muxes for a single, named channel. + * + * @param {string} channelName - The name of the channel. + * @param {ObjectMultiplex} muxA - The first mux. + * @param {ObjectMultiplex} muxB - The second mux. + */ +function forwardTrafficBetweenMuxes(channelName, muxA, muxB) { + const channelA = muxA.createStream(channelName); + const channelB = muxB.createStream(channelName); + pump(channelA, channelB, channelA, (err) => + logStreamDisconnectWarning( + `MetaMask muxed traffic for channel "${channelName}" failed.`, + err, + ), + ); +} + +/** + * Error handler for page to extension stream disconnections + * + * @param {string} remoteLabel - Remote stream name + * @param {Error} err - Stream connection error + */ +function logStreamDisconnectWarning(remoteLabel, err) { + let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`; + if (err) { + warningMsg += `\n${err.stack}`; + } + console.warn(warningMsg); + console.error(err); +} + +/** + * This function must ONLY be called in pump destruction/close callbacks. + * Notifies the inpage context that streams have failed, via window.postMessage. + * Relies on @metamask/object-multiplex and post-message-stream implementation details. + */ +function notifyProviderOfStreamFailure() { + window.postMessage( + { + target: INPAGE, // the post-message-stream "target" + data: { + // this object gets passed to object-multiplex + name: PROVIDER, // the object-multiplex channel name + data: { + jsonrpc: '2.0', + method: 'METAMASK_STREAM_FAILURE', + }, + }, + }, + window.location.origin, + ); +} diff --git a/scripts/inpage-bridge/inpage/webpack.config.js b/scripts/inpage-bridge/inpage/webpack.config.js new file mode 100644 index 00000000000..5e7fef71049 --- /dev/null +++ b/scripts/inpage-bridge/inpage/webpack.config.js @@ -0,0 +1,50 @@ +const webpack = require('webpack'); +const path = require('path'); + +const config = { + entry: './index.js', + + output: { + path: path.resolve(__dirname, '..', 'dist'), + filename: 'inpage-content.js', + }, + + mode: 'production', + module: { + rules: [ + { + test: /\.(js|jsx|mjs)$/u, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'], + }, + }, + }, + ], + }, + resolve: { + fallback: { + buffer: require.resolve('buffer'), + stream: require.resolve('stream-browserify'), + _stream_transform: require.resolve('readable-stream/transform'), + _stream_readable: require.resolve('readable-stream/readable'), + _stream_writable: require.resolve('readable-stream/writable'), + _stream_duplex: require.resolve('readable-stream/duplex'), + _stream_passthrough: require.resolve('readable-stream/passthrough'), + }, + }, + plugins: [ + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + process: 'process/browser', + }), + ], +}; + +module.exports = (_env, argv) => { + if (argv.mode === 'development') { + config.mode = 'development'; + } + return config; +}; diff --git a/scripts/inpage-bridge/webpack.config.js b/scripts/inpage-bridge/webpack.config.js new file mode 100644 index 00000000000..8c0dff54856 --- /dev/null +++ b/scripts/inpage-bridge/webpack.config.js @@ -0,0 +1,19 @@ +const path = require('path'); + +const config = { + entry: './dist/index-raw.js', + + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'index.js', + }, + + mode: 'production', +}; + +module.exports = (_env, argv) => { + if (argv.mode === 'development') { + config.mode = 'development'; + } + return config; +}; diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh index 97f4d9865cd..f6f059525c7 100755 --- a/scripts/postinstall.sh +++ b/scripts/postinstall.sh @@ -1,19 +1,24 @@ #!/bin/bash +set -euo pipefail + echo "PostInstall script:" -echo "1. React Native nodeify..." +echo "1. Build Inpage Bridge..." +./scripts/build-inpage-bridge.sh + +echo "2. React Native nodeify..." node_modules/.bin/rn-nodeify --install 'crypto,buffer,react-native-randombytes,vm,stream,http,https,os,url,net,fs' --hack -echo "2. jetify" +echo "3. jetify" yarn jetify -echo "3. Patch npm packages" +echo "4. Patch npm packages" yarn patch-package -echo "4. Create xcconfig files..." +echo "5. Create xcconfig files..." echo "" > ios/debug.xcconfig echo "" > ios/release.xcconfig -echo "5. Init git submodules" +echo "6. Init git submodules" echo "This may take a while..." git submodule update --init diff --git a/yarn.lock b/yarn.lock index 1f460eae619..55f7cba7137 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1588,6 +1588,11 @@ enabled "2.0.x" kuler "^2.0.0" +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + "@egjs/hammerjs@^2.0.17": version "2.0.17" resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" @@ -3799,14 +3804,14 @@ immer "^9.0.6" uuid "^8.3.2" -"@metamask/json-rpc-engine@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-7.0.0.tgz#5110d7e90a75aab4e515621fafff5adf7174b6e3" - integrity sha512-qIfQvEOD3vFMZpXQUcXjuVDnkznzjARRSa9mUjZnYImhoxgvPdTery31I+zkRuksNLffvJc08SL2cQaC3uVfYA== +"@metamask/json-rpc-engine@^7.0.0", "@metamask/json-rpc-engine@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-7.1.1.tgz#90d4c1e1fe3bcfc983563f6e07715319b8857190" + integrity sha512-wPB8Or74OqMwcxa87JPOEjXwtgpyHPEXiLKblKRAtCjTJNQFp1Co//1CgFm5xj4Z5JbBGfGFiQNnj09Et40sig== dependencies: - "@metamask/rpc-errors" "^5.0.0" - "@metamask/safe-event-emitter" "^2.0.0" - "@metamask/utils" "^5.0.1" + "@metamask/rpc-errors" "^6.0.0" + "@metamask/safe-event-emitter" "^3.0.0" + "@metamask/utils" "^8.1.0" "@metamask/keyring-controller@^6.0.0": version "6.1.0" @@ -3876,6 +3881,15 @@ uuid "^8.3.2" web3-provider-engine "^16.0.5" +"@metamask/object-multiplex@^1.1.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@metamask/object-multiplex/-/object-multiplex-1.2.0.tgz#38fc15c142f61939391e1b9a8eed679696c7e4f4" + integrity sha512-hksV602d3NWE2Q30Mf2Np1WfVKaGqfJRy9vpHAmelbaD0OkDt06/0KQkRR6UVYdMbTbkuEu8xN5JDUU80inGwQ== + dependencies: + end-of-stream "^1.4.4" + once "^1.4.0" + readable-stream "^2.3.3" + "@metamask/obs-store@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@metamask/obs-store/-/obs-store-7.0.0.tgz#6cae5f28306bb3e83a381bc9ae22682316095bd3" @@ -3948,12 +3962,29 @@ "@metamask/base-controller" "^3.2.1" "@metamask/controller-utils" "^4.3.2" -"@metamask/rpc-errors@^5.0.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@metamask/rpc-errors/-/rpc-errors-5.1.1.tgz#f82732ad0952d34d219eca42699c0c74bee95a9e" - integrity sha512-JjZnDi2y2CfvbohhBl+FOQRzmFlJpybcQlIk37zEX8B96eVSPbH/T8S0p7cSF8IE33IWx6JkD8Ycsd+2TXFxCw== +"@metamask/providers@^13.0.0": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@metamask/providers/-/providers-13.1.0.tgz#c5aef8e7073e097e6693cffc5f463b0632e1f1fd" + integrity sha512-/2Ti81CwZ/9LLpAm9Law+7z1PYbR3EiNXNKCbkppOfxxR1MbC2ps8/GFTjk7UHEMhAVG4k9ziGW8mMsutNVxmA== + dependencies: + "@metamask/json-rpc-engine" "^7.1.1" + "@metamask/object-multiplex" "^1.1.0" + "@metamask/rpc-errors" "^6.0.0" + "@metamask/safe-event-emitter" "^3.0.0" + "@metamask/utils" "^8.1.0" + detect-browser "^5.2.0" + extension-port-stream "^2.1.1" + fast-deep-equal "^3.1.3" + is-stream "^2.0.0" + json-rpc-middleware-stream "^4.2.1" + webextension-polyfill "^0.10.0" + +"@metamask/rpc-errors@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@metamask/rpc-errors/-/rpc-errors-6.1.0.tgz#dfdef7cba4b9ad01ca3f99e990b5980575b89b4f" + integrity sha512-JQElKxai26FpDyRKO/yH732wI+BV90i1u6pOuDOpdADSbppB2g1pPh3AGST1zkZqEE9eIKIUw8UdBQ4rp3VTSg== dependencies: - "@metamask/utils" "^5.0.0" + "@metamask/utils" "^8.1.0" fast-safe-stringify "^2.0.6" "@metamask/safe-event-emitter@^2.0.0": @@ -4059,7 +4090,7 @@ semver "^7.3.8" superstruct "^1.0.3" -"@metamask/utils@^5.0.0", "@metamask/utils@^5.0.1", "@metamask/utils@^5.0.2": +"@metamask/utils@^5.0.1", "@metamask/utils@^5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-5.0.2.tgz#140ba5061d90d9dac0280c19cab101bc18c8857c" integrity sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g== @@ -8898,6 +8929,21 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@webpack-cli/configtest@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== + +"@webpack-cli/info@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== + +"@webpack-cli/serve@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== + "@xmldom/xmldom@^0.x": version "0.8.6" resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.6.tgz#8a1524eb5bd5e965c1e3735476f0262469f71440" @@ -11823,7 +11869,7 @@ clipboard@^2.0.0: cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -11999,7 +12045,7 @@ colorette@^1.0.7, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -colorette@^2.0.10: +colorette@^2.0.10, colorette@^2.0.14: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -13176,7 +13222,7 @@ detect-browser@5.2.0: resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.2.0.tgz#c9cd5afa96a6a19fda0bbe9e9be48a6b6e1e9c97" integrity sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA== -detect-browser@5.3.0: +detect-browser@5.3.0, detect-browser@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== @@ -13712,7 +13758,7 @@ encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0, end-of-stream@^1.4.1: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1, end-of-stream@^1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -13774,10 +13820,10 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -envinfo@^7.7.2: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== +envinfo@^7.7.2, envinfo@^7.7.3: + version "7.10.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" + integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== enzyme-adapter-react-16@1.10.0: version "1.10.0" @@ -15276,6 +15322,13 @@ extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +extension-port-stream@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/extension-port-stream/-/extension-port-stream-2.1.1.tgz#ec11f2a5ed95655d8c40805d7cb0c39939ee9ef4" + integrity sha512-qknp5o5rj2J9CRKfVB8KJr+uXQlrojNZzdESUPhKYLXf97TPcGf6qWWKmpsNNtUyOdzFhab1ON0jzouNxHHvow== + dependencies: + webextension-polyfill ">=0.10.0 <1.0" + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -15417,6 +15470,11 @@ fast-xml-parser@4.2.4, fast-xml-parser@^4.0.12: dependencies: strnum "^1.0.5" +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + fastq@^1.6.0: version "1.12.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.12.0.tgz#ed7b6ab5d62393fb2cc591c853652a5c318bf794" @@ -17097,7 +17155,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -17167,6 +17225,11 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + invariant@*, invariant@2, invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -18554,6 +18617,15 @@ json-rpc-middleware-stream@3.0.0: "@metamask/safe-event-emitter" "^2.0.0" readable-stream "^2.3.3" +json-rpc-middleware-stream@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/json-rpc-middleware-stream/-/json-rpc-middleware-stream-4.2.3.tgz#08340846ffaa2a60287930773546eb4b7f7dbba2" + integrity sha512-4iFb0yffm5vo3eFKDbQgke9o17XBcLQ2c3sONrXSbcOLzP8LTojqo8hRGVgtJShhm5q4ZDSNq039fAx9o65E1w== + dependencies: + "@metamask/safe-event-emitter" "^3.0.0" + json-rpc-engine "^6.1.0" + readable-stream "^2.3.3" + json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" @@ -21638,15 +21710,6 @@ ob1@0.73.9: resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.9.tgz#d5677a0dd3e2f16ad84231278d79424436c38c59" integrity sha512-kHOzCOFXmAM26fy7V/YuXNKne2TyRiXbFAvPBIbuedJCZZWQZHLdPzMeXJI4Egt6IcfDttRzN3jQ90wOwq1iNw== -obj-multiplex@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/obj-multiplex/-/obj-multiplex-1.0.0.tgz#2f2ae6bfd4ae11befe742ea9ea5b36636eabffc1" - integrity sha1-Lyrmv9SuEb7+dC6p6ls2Y26r/8E= - dependencies: - end-of-stream "^1.4.0" - once "^1.4.0" - readable-stream "^2.3.3" - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -24347,26 +24410,29 @@ read@1.0.x: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.0.33: - version "1.0.33" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.33.tgz#3a360dd66c1b1d7fd4705389860eda1d0f61126c" - integrity sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== +"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, readable-stream@^1.0.31, readable-stream@^1.0.33: +readable-stream@2.3.7: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^1.0.26-4, readable-stream@^1.0.31, readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= @@ -24456,6 +24522,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + recursive-readdir@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" @@ -25990,13 +26063,13 @@ store2@^2.12.0, store2@^2.14.2, store2@^2.7.1: resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== -stream-browserify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-1.0.0.tgz#bf9b4abfb42b274d751479e44e0ff2656b6f1193" - integrity sha1-v5tKv7QrJ011FHnkTg/yZWtvEZM= +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== dependencies: - inherits "~2.0.1" - readable-stream "^1.0.27-1" + inherits "~2.0.4" + readable-stream "^3.5.0" stream-browserify@^2.0.1: version "2.0.2" @@ -27947,6 +28020,11 @@ webdriverio@~7.16.13: serialize-error "^8.0.0" webdriver "7.16.16" +"webextension-polyfill@>=0.10.0 <1.0", webextension-polyfill@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz#ccb28101c910ba8cf955f7e6a263e662d744dbb8" + integrity sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -27957,6 +28035,25 @@ webidl-conversions@^5.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== +webpack-cli@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" + integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^2.1.1" + "@webpack-cli/info" "^2.0.2" + "@webpack-cli/serve" "^2.0.5" + colorette "^2.0.14" + commander "^10.0.1" + cross-spawn "^7.0.3" + envinfo "^7.7.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^5.7.3" + webpack-dev-middleware@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz#179cc40795882cae510b1aa7f3710cbe93c9333e" @@ -27989,6 +28086,14 @@ webpack-hot-middleware@^2.25.1: html-entities "^2.1.0" strip-ansi "^6.0.0" +webpack-merge@^5.7.3: + version "5.9.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" + integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" @@ -28041,7 +28146,7 @@ webpack@4: watchpack "^1.7.4" webpack-sources "^1.4.1" -webpack@5, webpack@^5.9.0: +webpack@5, webpack@^5.88.2, webpack@^5.9.0: version "5.88.2" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== @@ -28173,6 +28278,11 @@ wide-align@^1.1.0, wide-align@^1.1.2, wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa"