Skip to content

Commit

Permalink
Add global initialization event (#31)
Browse files Browse the repository at this point in the history
* add global initialization event

* add init function

Co-authored-by: Mark Stacey <[email protected]>
  • Loading branch information
rekmarks and Gudahtt authored Apr 20, 2020
1 parent 89e06b8 commit ea0b419
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 2 deletions.
9 changes: 8 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
module.exports = require('./src/MetamaskInpageProvider')
const MetamaskInpageProvider = require('./src/MetamaskInpageProvider')
const { initProvider, setGlobalProvider } = require('./src/initProvider')

module.exports = {
MetamaskInpageProvider,
initProvider,
setGlobalProvider,
}
19 changes: 18 additions & 1 deletion src/MetamaskInpageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,29 @@ const {

module.exports = class MetamaskInpageProvider extends SafeEventEmitter {

constructor (connectionStream, shouldSendMetadata = true) {
/**
* @param {Object} connectionStream - A Node.js stream
* @param {Object} opts - An options bag
* @param {number} opts.maxEventListeners - The maximum number of event listeners
* @param {boolean} opts.shouldSendMetadata - Whether the provider should send page metadata
*/
constructor (
connectionStream,
{ shouldSendMetadata = true, maxEventListeners = 100 },
) {

if (
typeof shouldSendMetadata !== 'boolean' || typeof maxEventListeners !== 'number'
) {
throw new Error('Invalid options.')
}

super()

this.isMetaMask = true

this.setMaxListeners(maxEventListeners)

// private state, kept here in part for use in the _metamask proxy
this._state = {
sentWarnings: {
Expand Down
59 changes: 59 additions & 0 deletions src/initProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const MetamaskInpageProvider = require('./MetamaskInpageProvider')

/**
* Initializes a MetamaskInpageProvider and (optionally) sets it on window.ethereum.
*
* @param {Object} opts - An options bag.
* @param {Object} opts.connectionStream - A Node.js stream.
* @param {number} opts.maxEventListeners - The maximum number of event listeners.
* @param {boolean} opts.preventPropertyDeletion - Whether to wrap the provider in a proxy that prevents property deletion.
* @param {boolean} opts.shouldSendMetadata - Whether the provider should send page metadata.
* @param {boolean} opts.shouldSetOnWindow - Whether the provider should be set as window.ethereum
* @returns {MetamaskInpageProvider | Proxy} The initialized provider (whether set or not).
*/
function initProvider ({
connectionStream,
maxEventListeners = 100,
preventPropertyDeletion = true,
shouldSendMetadata = true,
shouldSetOnWindow = true,
}) {

if (!connectionStream) {
throw new Error('Must provide a connection stream.')
}

let provider = new MetamaskInpageProvider(
connectionStream, { shouldSendMetadata, maxEventListeners },
)

if (preventPropertyDeletion) {
// Workaround for [email protected] deleting the bound `sendAsync` but not the unbound
// `sendAsync` method on the prototype, causing `this` reference issues
provider = new Proxy(provider, {
deleteProperty: () => true,
})
}

if (shouldSetOnWindow) {
setGlobalProvider(provider)
}

return provider
}

/**
* Sets the given provider instance as window.ethereum and dispatches the
* 'ethereum#initialized' event on window.
*
* @param {MetamaskInpageProvider} providerInstance - The provider instance.
*/
function setGlobalProvider (providerInstance) {
window.ethereum = providerInstance
window.dispatchEvent(new Event('ethereum#initialized'))
}

module.exports = {
initProvider,
setGlobalProvider,
}

0 comments on commit ea0b419

Please sign in to comment.