diff options
Diffstat (limited to 'app/scripts/createStandardProvider.js')
-rw-r--r-- | app/scripts/createStandardProvider.js | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/app/scripts/createStandardProvider.js b/app/scripts/createStandardProvider.js new file mode 100644 index 000000000..a5f9c5d03 --- /dev/null +++ b/app/scripts/createStandardProvider.js @@ -0,0 +1,92 @@ +class StandardProvider { + _isConnected + _provider + + constructor (provider) { + this._provider = provider + this._onMessage('ethereumpingerror', this._onClose.bind(this)) + this._onMessage('ethereumpingsuccess', this._onConnect.bind(this)) + window.addEventListener('load', () => { + this._subscribe() + this._ping() + }) + } + + _onMessage (type, handler) { + window.addEventListener('message', function ({ data }) { + if (!data || data.type !== type) return + handler.apply(this, arguments) + }) + } + + _onClose () { + if (this._isConnected === undefined || this._isConnected) { + this._provider.emit('close', { + code: 1011, + reason: 'Network connection error', + }) + } + this._isConnected = false + } + + _onConnect () { + !this._isConnected && this._provider.emit('connect') + this._isConnected = true + } + + async _ping () { + try { + await this.send('net_version') + window.postMessage({ type: 'ethereumpingsuccess' }, '*') + } catch (error) { + window.postMessage({ type: 'ethereumpingerror' }, '*') + } + } + + _subscribe () { + this._provider.on('data', (error, { method, params }) => { + if (!error && method === 'eth_subscription') { + this._provider.emit('notification', params.result) + } + }) + } + + /** + * Initiate an RPC method call + * + * @param {string} method - RPC method name to call + * @param {string[]} params - Array of RPC method parameters + * @returns {Promise<*>} Promise resolving to the result if successful + */ + send (method, params = []) { + if (method === 'eth_requestAccounts') return this._provider.enable() + + return new Promise((resolve, reject) => { + try { + this._provider.sendAsync({ method, params, beta: true }, (error, response) => { + error = error || response.error + error ? reject(error) : resolve(response) + }) + } catch (error) { + reject(error) + } + }) + } +} + +/** + * Converts a legacy provider into an EIP-1193-compliant standard provider + * @param {Object} provider - Legacy provider to convert + * @returns {Object} Standard provider + */ +export default function createStandardProvider (provider) { + const standardProvider = new StandardProvider(provider) + const sendLegacy = provider.send + provider.send = (methodOrPayload, callbackOrArgs) => { + if (typeof methodOrPayload === 'string' && !callbackOrArgs || Array.isArray(callbackOrArgs)) { + return standardProvider.send(methodOrPayload, callbackOrArgs) + } + return sendLegacy.call(provider, methodOrPayload, callbackOrArgs) + } + return provider +} |