var HttpProvider = require('web3/lib/web3/httpprovider.js') var ethUtils = require('ethereumjs-util') var async = require('async') module.exports = MetamaskProvider function MetamaskProvider(forwardPayload, host) { this.handlers = [] this.forwardPayload = forwardPayload this.http = new HttpProvider(host) } MetamaskProvider.prototype.send = function (payload) { if (Array.isArray(payload)) { return payload.map( this.handlePayload.bind(this) ) } else { return this.handlePayload( payload ) } } MetamaskProvider.prototype.sendAsync = function (payload, cb) { if (Array.isArray(payload)) { async.map( payload, this.handlePayload.bind(this), cb ) } else { this.handlePayload( payload, cb ) } } MetamaskProvider.prototype.handlePayload = function (payload, cb) { var _this = this var isSync = !cb var resolvedSync = true var result = undefined // TODO - this should be injected from Vapor dapp starts var exposedAccounts = ['0xa06ef3ed1ce41ade87f764de6ce8095c569d6d57'] switch (payload.method) { case 'web3_sha3': var inputHex = stripHexStringPrefix(payload.params[0]) var hash = '0x'+ethUtils.sha3(new Buffer(inputHex, 'hex')).toString('hex') return handleResult(null, wrapResponse(payload, hash)) case 'eth_sendTransaction': this.forwardPayload(payload) return handleResult(null, wrapResponse(payload, '')) case 'eth_coinbase': var currentAddress = exposedAccounts[0] return handleResult(null, wrapResponse(payload, currentAddress)) case 'eth_accounts': return handleResult(null, wrapResponse(payload, exposedAccounts)) case 'eth_gasPrice': // TODO - this should be dynamically set somehow var gasPrice = '0x01' return handleResult(null, wrapResponse(payload, [gasPrice])) case 'eth_call': var params = payload.params // default 'from' to default account var args = params[0] if (!args.from) { var currentAddress = exposedAccounts[0] args.from = currentAddress } // default block to latest params[1] = params[1] || 'latest' // turn on debug trace params[2] = global.DEBUG_RPC return handleNormally() default: return handleNormally() } resolvedSync = false function handleNormally(){ if (isSync) { return handleResult(null, _this.http.send(payload)) } else { _this.http.sendAsync(payload, handleResult) } } // helper for normalizing handling of sync+async responses function handleResult(err, resp) { if (isSync) { return resp } else { if (resolvedSync) { process.nextTick(cb.bind(null, err, resp)) } else { cb(err, resp) } } } } function wrapResponse(payload, result){ return { jsonrpc: payload.jsonrpc, id: payload.id, result: result, } } function stripHexStringPrefix(hex) { if (!hex) { return hex } if (hex.slice(0, 2) === '0x') { return hex.slice(2); } else { return hex; } }