aboutsummaryrefslogblamecommitdiffstats
path: root/app/scripts/metamask-provider.js
blob: c52de82b403851137580be6c5752c4c6d42c330f (plain) (tree)

























































































































                                                                                
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;
  }
}